我們已經看到了帶有 ?get
?的 ?Moralis.Query
? 如何從 Moralis 中檢索單個 ?Moralis.Object
?。 還有許多其他方法可以使用 ?Moralis.Query
? 檢索數(shù)據。 您可以一次檢索多個對象,對要檢索的對象設置條件等等。
在許多情況下,?get
?功能不足以指定要檢索的對象。 ?Moralis.Query
? 提供了不同的方法來檢索對象列表,而不僅僅是單個對象。
一般模式是創(chuàng)建一個 ?Moralis.Query
?,在其上設置條件,然后使用 ?find
?檢索匹配的 ?Moralis.Objects
? 數(shù)組。 例如,要檢索具有特定 ?ownerName
? 的monster,請使用 ?equalTo
?方法來約束鍵的值。
你可以使用?JS
?、?React
?、?Unity
?來實現(xiàn)
const Monster = Moralis.Object.extend("Monster");
const query = new Moralis.Query(Monster);
query.equalTo("ownerName", "Aegon");
const results = await query.find();
alert("Successfully retrieved " + results.length + " monsters.");
// Do something with the returned Moralis.Object values
for (let i = 0; i < results.length; i++) {
const object = results[i];
alert(object.id + " - " + object.get("ownerName"));
}
import { useMoralisQuery } from "react-moralis";
export default function App() {
const { fetch } = useMoralisQuery(
"Monster",
(query) => query.equalTo("ownerName", "Aegon"),
[],
{ autoFetch: false }
);
const basicQuery = async () => {
const results = await fetch();
alert("Successfully retrieved " + results.length + " monsters.");
// Do something with the returned Moralis.Object values
for (let i = 0; i < results.length; i++) {
const object = results[i];
alert(object.id + " - " + object.get("ownerName"));
}
};
return <button onClick={basicQuery}>Call The Code</button>;
}
using Moralis.Platform.Objects;
using MoralisWeb3ApiSdk;
using Newtonsoft.Json;
public async void RetrieveObjectFromDB()
{
MoralisQuery<Monster> monster = MoralisInterface.GetClient().Query<Monster>().WhereEqualTo("ownerName", "Aegon");
IEnumerable<Monster> result = await monster.FindAsync();
foreach(Monster mon in result)
{
print("My strength is " + mon.strength + " and can i fly ? " + mon.canFly);
// output : My strength is 1024 and can i fly ? true
}
}
在某些情況下,查詢需要主密鑰,
例如,如果您想獲取所有用戶的列表,您只能使用主密鑰在云功能中執(zhí)行此操作 - 因為由于 ACL,用戶無法讀取其他用戶的信息。
query.find({ useMasterKey: true });
有幾種方法可以對 ?Moralis.Query
? 找到的對象施加約束。 您可以使用 ?notEqualTo
?過濾掉具有特定鍵值對的對象:
query.notEqualTo("ownerName", "Daenerys");
您可以提供多個約束,并且對象只有在匹配所有約束時才會出現(xiàn)在結果中。 換句話說,它就像約束的 ?AND
?。
query.notEqualTo("ownerName", "Daenerys");
query.greaterThan("ownerAge", 18);
您可以通過設置限制來限制結果的數(shù)量。 默認情況下,結果限制為 100。在舊的 Moralis 托管后端中,最大限制為 1,000,但 Moralis Dapps 現(xiàn)在刪除了該限制:
query.limit(10); // limit to at most 10 results
如果您只想要一個結果,更方便的替代方法可能是使用?first
?而不是使用 ?find
?(可以通過?JS
?、?React
?實現(xiàn))。
const Monster = Moralis.Object.extend("Monster");
const query = new Moralis.Query(Monster);
query.equalTo("ownerEmail", "daenerys@housetargaryen.com");
const object = await query.first();
import { useMoralisQuery } from "react-moralis";
export default function App() {
const { fetch } = useMoralisQuery(
"Monster",
(query) =>
query.equalTo("ownerEmail", "daenerys@housetargaryen.com").first(),
[],
{ autoFetch: false }
);
const singleQuery = () =>
fetch({
onSuccess: (result) => console.log(result),
});
return <button onClick={singleQuery}>Call The Code</button>;
}
您可以通過設置 skip 來跳過第一個結果。 在舊的 Moralis 托管后端中,最大skip值為 10,000,但 Moralis Dapps 現(xiàn)在取消了該限制。 這對于分頁很有用:
query.skip(10); // skip the first 10 results
獲取滿足您查詢的表中的總行數(shù),例如 分頁目的 - 您可以使用 ?withCount
?。
注意:啟用此標志將更改響應的結構,請參見下面的示例。
示例 - 假設您在名為 Monster 的表中有 200 行(可以通過?JS
?、?React
?實現(xiàn)):
const Monster = Moralis.Object.extend("Monster");
const query = new Moralis.Query(Monster);
query.limit(25);
const results = await query.find(); // [ Monster, Monster, ...]
// to include count:
query.withCount();
const response = await query.find(); // { results: [ Monster, ... ], count: 200 }
const limitQuery = useMoralisQuery("Monster", (query) => query.limit(25), [], {
autoFetch: false,
});
const getLimitedQuery = () =>
limitQuery.fetch({
onSuccess: (result) => console.log(result), // [ Monster, Monster, ...]
});
const queryCount = useMoralisQuery(
"Monster",
(query) => query.withCount(),
[],
{
autoFetch: false,
}
);
const getQueryWithCount = () =>
queryCount.fetch({
onSuccess: (result) => console.log(result), // { results: [ Monster, ... ], count: 200 }
});
?
count
?操作可能會很慢而且很昂貴。
如果您只想獲取沒有對象的計數(shù) - 使用Counting Objects。
要對數(shù)字和字符串等可排序類型進行排序,您可以控制返回結果的順序:
// Sorts the results in ascending order by the strength field
query.ascending("strength");
// Sorts the results in descending order by the strength field
query.descending("strength");
要在可排序類型的查詢中進行比較:
// Restricts to wins < 50
query.lessThan("wins", 50);
// Restricts to wins <= 50
query.lessThanOrEqualTo("wins", 50);
// Restricts to wins > 50
query.greaterThan("wins", 50);
// Restricts to wins >= 50
query.greaterThanOrEqualTo("wins", 50);
要檢索在值列表中匹配的對象,您可以使用 ?containsIn
?,提供可接受值的數(shù)組。 這對于用單個查詢替換多個查詢通常很有用。
例如 - 如果您想檢索特定列表中任何monster所有者擁有的monster:
// Finds monsters from any of Jonathan, Dario, or Shawn
query.containedIn("ownerName", [
"Jonathan Walsh",
"Dario Wunsch",
"Shawn Simon",
]);
要檢索與多個值中的任何一個都不匹配的對象,您可以使用 ?notContainedIn
?,提供一個可接受值的數(shù)組。
例如,如果您想從列表中的monster所有者那里檢索monster:
// Finds monsters from anyone who is neither Jonathan, Dario, nor Shawn
query.notContainedIn("ownerName", [
"Jonathan Walsh",
"Dario Wunsch",
"Shawn Simon",
]);
要檢索具有特定鍵集的對象,您可以使用 ?exists
?。 相反,如果要檢索沒有特定鍵集的對象,可以使用 ?doesNotExist
?。
// Finds objects that have the strength set
query.exists("strength");
// Finds objects that don't have the strength set
query.doesNotExist("strength");
獲取鍵與另一個查詢產生的一組對象中的鍵值匹配的對象。 您可以使用?matchesKeyInQuery
?方法。
例如,如果您有一個包含運動隊的類,并且您在用戶類中存儲了用戶的家鄉(xiāng),則可以發(fā)出一次查詢以查找家鄉(xiāng)球隊有獲勝記錄的用戶列表。 查詢將如下所示:
const Team = Moralis.Object.extend("Team");
const teamQuery = new Moralis.Query(Team);
teamQuery.greaterThan("winPct", 0.5);
const userQuery = new Moralis.Query(Moralis.User);
userQuery.matchesKeyInQuery("hometown", "city", teamQuery);
// results has the list of users with a hometown team with a winning record
const results = await userQuery.find();
相反,要獲取鍵與另一個查詢產生的一組對象中的鍵值不匹配的對象,請使用 ?doesNotMatchKeyInQuery
?。 例如,查找家鄉(xiāng)球隊有輸球記錄的用戶:
const losingUserQuery = new Moralis.Query(Moralis.User);
losingUserQuery.doesNotMatchKeyInQuery("hometown", "city", teamQuery);
// results has the list of users with a hometown team with a losing record
const results = await losingUserQuery.find();
要根據 ?objectId
?從第二個表中的指針過濾行,可以使用點表示法:
const rolesOfTypeX = new Moralis.Query("Role");
rolesOfTypeX.equalTo("type", "x");
const groupsWithRoleX = new Moralis.Query("Group");
groupsWithRoleX.matchesKeyInQuery(
"objectId",
"belongsTo.objectId",
rolesOfTypeX
);
groupsWithRoleX.find().then(function (results) {
// results has the list of groups with role x
});
通過使用鍵列表調用 ?select
?來限制返回的字段。
例如,要檢索僅包含 ?strength
?和 ?ownerName
?字段(以及特殊的內置字段,如 ?objectId
?、?createdAt
?和 ?updatedAt
?)的文檔:
你可以通過?JS
?、?React
?來實現(xiàn)
const Monster = Moralis.Object.extend("Monster");
const query = new Moralis.Query(Monster);
query.select("strength", "ownerName");
query.find().then(function (monsters) {
// each of the monsters will only have the selected fields available.
});
import { useMoralisQuery } from "react-moralis";
export default function App() {
const { fetch } = useMoralisQuery(
"Monster",
(query) => query.select("strength", "ownerName"),
[],
{ autoFetch: false }
);
const getSelectedQuery = () =>
fetch({
onSuccess: (monster) => {
// each of the monsters will only have the selected fields available.
},
});
return <button onClick={getSelectedQuery}>Call The Code</button>;
}
同樣,要在檢索其余字段時刪除不需要的字段,請使用 ?exclude
?(可以通過?JS
?、?React
?來實現(xiàn)):
const Monster = Moralis.Object.extend("Monster");
const query = new Moralis.Query(Monster);
query.exclude("ownerName");
query.find().then(function (monsters) {
// Now each monster will have all fields except `ownerName`
});
import { useMoralisQuery } from "react-moralis";
export default function App() {
const { fetch } = useMoralisQuery(
"Monster",
(query) => query.exclude("ownerName"),
[],
{ autoFetch: false }
);
const queryExcludingParam = () =>
fetch({
onSuccess: (monsters) => {
// Now each monster will have all fields except `ownerName`
},
});
return <button onClick={queryExcludingParam}>Call The Code</button>;
}
稍后可以通過對返回的對象調用 ?fetch
?來獲取剩余的字段:
query
.first()
.then(function (result) {
// only the selected fields of the object will now be available here.
return result.fetch();
})
.then(function (result) {
// all fields of the object will now be available here.
});
請記住在對?
address
?列進行查詢約束時確保?addresses
?為小寫。
對于數(shù)組類型的鍵,您可以通過以下方式找到鍵的數(shù)組值包含 2 的對象:
// Find objects where the array in arrayKey contains 2.
query.equalTo("arrayKey", 2);
您還可以找到鍵的數(shù)組值包含每個元素 2、3 和 4 的對象,其中包含以下內容:
// Find objects where the array in arrayKey contains all of the elements 2, 3, and 4.
query.containsAll("arrayKey", [2, 3, 4]);
注意:可以直接在“?Moralis Dashboard
?”中運行查詢代碼。 可以通過導航到菜單中的“API 控制臺 > JS 控制臺”找到它。 這是一個在首次構建查詢時玩耍的好地方,因為它不需要任何設置或初始化。 它的功能與瀏覽器中的 JavaScript 控制臺完全相同,只是它可以直接訪問 Moralis SDK 和主密鑰。
完全按照您在客戶端或云代碼中的方式鍵入查詢。 包括一個 ?console.log()
? 來打印結果,然后按“運行”按鈕。 需要注意的一些差異:
Parse
?關鍵字而不是 MoralisParse.Query("EthTokenTransfers")
?$
?。const results = query.find({ useMasterKey: true })
?可以通過單擊“保存”在會話之間保存代碼。
使用 ?startsWith
?限制以特定字符串開頭的字符串值。 與 MySQL LIKE 運算符類似,這是索引的,因此對于大型數(shù)據集很有效:
// Finds barbecue sauces that start with "Big Daddy's".
const query = new Moralis.Query(BarbecueSauce);
query.startsWith("name", "Big Daddy's");
上面的示例將匹配“name”字符串鍵中的值以“Big Daddy's”開頭的任何 BarbecueSauce 對象。 例如,“Big Daddy's”和“Big Daddy's BBQ”都會匹配,但“big daddy's”或“BBQ Sauce: Big Daddy's”不匹配。
具有正則表達式約束的查詢非常昂貴,尤其是對于超過 100,000 條記錄的類。 Moralis 限制在任何給定時間可以在特定應用程序上運行的操作數(shù)。
使用全文以獲得高效的搜索功能。 文本索引會自動為您創(chuàng)建。 您的字符串將轉換為標記以進行快速搜索。
注意:全文搜索可能是資源密集型的。 確保使用索引的成本物有所值。
const query = new Moralis.Query(BarbecueSauce);
query.fullText("name", "bbq");
上面的示例將匹配“name”字符串鍵中的值包含“bbq”的任何 BarbecueSauce 對象。 例如,“Big Daddy's BBQ”、“Big Daddy's bbq”和“Big BBQ Daddy”都將匹配。
// You can sort by weight / rank. ascending() and select()
const query = new Moralis.Query(BarbecueSauce);
query.fullText("name", "bbq");
query.ascending("$score");
query.select("$score");
query
.find()
.then(function (results) {
// results contains a weight / rank in result.get('score')
})
.catch(function (error) {
// There was an error.
});
有幾種方法可以發(fā)出對關系數(shù)據的查詢。 要檢索字段與特定 ?Moralis.Object
? 匹配的對象,您可以使用 ?equalTo
?,就像其他數(shù)據類型一樣。
例如,如果每個 ?Comment
?在其 ?post
?字段中都有一個 ?Post
?對象,您可以獲取特定 ?Post
?的評論:
// Assume Moralis.Object myPost was previously created.
const query = new Moralis.Query(Comment);
query.equalTo("post", myPost);
// comments now contains the comments for myPost
const comments = await query.find();
要檢索字段包含匹配不同查詢的 ?Moralis.Object
? 的對象,您可以使用 ?matchesQuery
?。 為了查找包含圖片的帖子的評論,您可以執(zhí)行以下操作:
const Post = Moralis.Object.extend("Post");
const Comment = Moralis.Object.extend("Comment");
const innerQuery = new Moralis.Query(Post);
innerQuery.exists("image");
const query = new Moralis.Query(Comment);
query.matchesQuery("post", innerQuery);
// comments now contains the comments for posts with images.
const comments = await query.find();
要檢索字段包含不匹配不同查詢的 ?Moralis.Object
? 的對象,您可以使用 ?doesNotMatchQuery
?。 要查找沒有圖片的帖子的評論,您可以執(zhí)行以下操作:
const Post = Moralis.Object.extend("Post");
const Comment = Moralis.Object.extend("Comment");
const innerQuery = new Moralis.Query(Post);
innerQuery.exists("image");
const query = new Moralis.Query(Comment);
query.doesNotMatchQuery("post", innerQuery);
// comments now contains the comments for posts without images.
const comments = await query.find();
您還可以通過 ?objectId
?進行關系查詢:
const post = new Post();
post.id = "1zEcyElZ80";
query.equalTo("post", post);
要在一個查詢中返回多種類型的相關對象,請使用 ?include
?方法。
例如,假設您正在檢索最后 10 條評論,并且您想同時檢索他們的相關帖子:
const query = new Moralis.Query(Comment);
// Retrieve the most recent ones
query.descending("createdAt");
// Only retrieve the last ten
query.limit(10);
// Include the post data with each comment
query.include("post");
// Comments now contains the last ten comments, and the "post" field
const comments = await query.find();
// has been populated. For example:
for (let i = 0; i < comments.length; i++) {
// This does not require a network access.
const post = comments[i].get("post");
}
做多級包括使用點符號。 使用以下查詢。
例如,如果您想包含評論的帖子和帖子的作者,您可以這樣做:
query.include(["post.author"]);
您可以通過多次調用 ?
include
?來發(fā)出包含多個字段的查詢。 此功能也適用于 ?Moralis.Query
? 助手,例如 ?first
?和 ?get
?。
注意:在舊的 Moralis 托管后端中,計數(shù)查詢的速率被限制為每分鐘最多 160 個請求。 他們還為包含 1,000 多個對象的類返回了不準確的結果。 但是,Moralis Dapp 已經消除了這兩個限制,并且可以計算遠高于 1,000 個的對象。
要計算有多少對象與查詢匹配,但您不需要檢索所有匹配的對象,可以使用 ?count
?而不是 ?find
?。
例如,要計算特定?monster
?擁有者擁有的?monster
?數(shù)量:
const Monster = Moralis.Object.extend("Monster");
const query = new Moralis.Query(Monster);
query.equalTo("ownerName", "Aegon");
const count = await query.count();
alert("Aegon has owned " + count + " monsters");
對于更復雜的查詢,您可能需要復合查詢。 復合查詢是子查詢的邏輯組合(例如“and”或“or”)。
注意:我們不支持復合查詢的子查詢中的 ?
GeoPoint
?或非過濾約束(例如 ?near
?、?withinGeoBox
?、?limit
?、?skip
?、?ascending/descending
?、?include
?)。
要查找與多個查詢之一匹配的對象,您可以使用 ?Moralis.Query.or
? 方法構造一個查詢,該查詢是傳入查詢的 ?OR
?。
例如,如果您想找到獲得很多勝利或少數(shù)勝利的玩家,您可以執(zhí)行以下操作:
const lotsOfWins = new Moralis.Query("Player");
lotsOfWins.greaterThan("wins", 150);
const fewWins = new Moralis.Query("Player");
fewWins.lessThan("wins", 5);
const mainQuery = Moralis.Query.or(lotsOfWins, fewWins);
mainQuery
.find()
.then(function (results) {
// results contains a list of players that either have won a lot of games or won only a few games.
})
.catch(function (error) {
// There was an error.
});
要查找符合所有條件的對象,通常只使用一個查詢。 您可以向新創(chuàng)建的 ?Moralis.Query
? 添加額外的約束,充當?and
?運算符。
const query = new Moralis.Query("User");
query.greaterThan("age", 18);
query.greaterThan("friends", 0);
query
.find()
.then(function (results) {
// results contains a list of users both older than 18 and having friends.
})
.catch(function (error) {
// There was an error.
});
有時比這個簡單的示例更復雜,您可能需要子查詢的復合查詢。 您可以使用 ?Moralis.Query.and
? 方法構造一個查詢,該查詢是傳入查詢的 ?AND
?。
例如,如果您想查找 16 歲或 18 歲且沒有朋友或至少有兩個朋友的用戶,您可以執(zhí)行以下操作:
const age16Query = new Moralis.Query("User");
age16Query.equalTo("age", 16);
const age18Query = new Moralis.Query("User");
age18Query.equalTo("age", 18);
const friends0Query = new Moralis.Query("User");
friends0Query.equalTo("friends", 0);
const friends2Query = new Moralis.Query("User");
friends2Query.greaterThan("friends", 2);
const mainQuery = Moralis.Query.and(
Moralis.Query.or(age16Query, age18Query),
Moralis.Query.or(friends0Query, friends2Query)
);
mainQuery
.find()
.then(function (results) {
// results contains a list of users in the age of 16 or 18 who have either no friends or at least 2 friends
// results: (age 16 or 18) and (0 or >2 friends)
})
.catch(function (error) {
// There was an error.
});
可以使用聚合進行查詢,允許您通過一組輸入值檢索對象。 結果不會是 ?Moralis.Objects
?,因為您將聚合自己的字段。
?
MasterKey
?是必需的。
聚合使用階段通過將結果從一個階段傳遞到下一個階段來過濾結果。 前一階段的輸出成為下一階段的輸入。
您可以使用數(shù)組或對象創(chuàng)建管道。
const pipelineObject = {
group: { objectId: "$name" },
};
const pipelineArray = [{ group: { objectId: "$name" } }];
有關可用階段的列表,請參閱 Mongo 聚合文檔。
注意:Mongo 聚合文檔中的大多數(shù)操作都適用于 ?
Moralis Server
?,但 ?_id
? 不存在。 請?zhí)鎿Q為 ?objectId
?。
Match管道類似于equalTo。
const pipeline = [{ match: { name: "BBQ" } }];
const query = new Moralis.Query("User");
query
.aggregate(pipeline)
.then(function (results) {
// results contains name that matches 'BBQ'
})
.catch(function (error) {
// There was an error.
});
您可以通過比較來匹配。
const pipeline = [{ match: { score: { $gt: 15 } } }];
const query = new Moralis.Query("User");
query
.aggregate(pipeline)
.then(function (results) {
// results contains score greater than 15
})
.catch(function (error) {
// There was an error.
});
您可以在 Mongo 查詢運算符文檔中閱讀有關可用運算符的更多信息。
lookup管道類似于 SQL 中的 LEFT OUTER JOIN。 它將匹配另一個集合中的文檔并將它們作為數(shù)組屬性帶入結果中。
例如,在投資組合應用程序中,您可能希望顯示用戶的所有代幣交易。 在 Moralis 中,這些存儲在 ?EthTokenTransfers
?集合中。 除了令牌名稱和小數(shù)位數(shù)之外,此集合包含所需的所有信息,這些信息是在前端以一種很好的方式顯示此信息所必需的。 額外的信息在 ?EthTokenBalance
?集合中,為了得到它,我們需要查找。 有關更多詳細信息,請查看 Mongo lookup文檔。
不幸的是,對于我們的用例,?EthTokenBalance
?集合不僅包含我們當前用戶的信息,還包含所有用戶的信息。 這意味著每個持有該令牌的用戶都會重復該令牌名稱。 這意味著加入多個屬性,它需要不同的語法,下面將介紹。 現(xiàn)在,假設我們有另一個名為 ?Token
?的集合,它看起來像這樣:
Token {
objectId: string,
token_address: string,
symbol: string,
name: string,
decimals: number
}
然后你會定義一個這樣的云函數(shù)(聚合查詢必須在云代碼中運行)。
記住要像 ?
\$
? 一樣轉義 ?$
? 以防止解析錯誤(現(xiàn)在已修復?。?。
// this goes in the Moralis server Cloud Functions section
Moralis.Cloud.define("getUserTokenTransfers", function (request) {
const userAddress = request.params.userAddress;
const query = new Moralis.Query("EthTokenTransfers");
const pipeline = [
// only transfers to or from userAddress
{
match: {
$expr: {
$or: [
{ $eq: ["$from_address", userAddress] },
{ $eq: ["$to_address", userAddress] },
],
},
},
},
// join to Token collection on token_address
{
lookup: {
from: "Token",
localField: "token_address",
foreignField: "token_address",
as: "token",
},
},
];
return query.aggregate(pipeline);
});
輸出如下所示: “?token
?”指定 ?Token
?表中匹配文檔的輸出數(shù)組的名稱。 如果連接是一對多而不是一對一,則此數(shù)組的長度將大于 1。
[
{
// EthTokenTransfer collection attributes
"block_timestamp":{...}
"token_address": "0x8762db106b2c2a0bccb3a80d1ed41273552616e8"
"from_address": "0xba65016890709dbc9491ca7bf5de395b8441dc8b"
"to_address": "0x29781d9fca70165cbc952b8c558d528b85541f0b"
"value": "29803465370630263212090"
"transaction_hash": "0xfc611dbae7c67cd938fca58a0cc2fe46d224f71b91472d4c9241e997e6440ac1"
"token": [
{
// Token collection attributes from lookup
"_id": "HKA8dzHG1A"
"token_address": "0x8762db106b2c2a0bccb3a80d1ed41273552616e8"
"symbol": "RSR"
"name": "Reserve Rights"
"decimals": 18
}
]
}
]
連接多個屬性需要在查找中使用嵌套管道,但在定義集合應如何連接時提供了更大的靈活性。 上面的查詢可以重寫以加入 ?EthTokenTranfers
?和 ?EthTokenBalance
?。
// this goes in the Moralis server Cloud Functions section
Moralis.Cloud.define("getUserTokenTransfers", function(request) {
const userAddress = request.params.userAddress;
const query = new Moralis.Query("EthTokenTransfers");
const pipeline = [
// only transfers to or from userAddress
{match: {$expr: {$or: [
{$eq: ["$from_address", userAddress]},
{$eq: ["$to_address", userAddress]},
]}}},
// join to EthTokenBalance on token_address and userAddress
{lookup: {
from: "EthTokenBalance",
let: { tokenAddress: "$token_address", userAddress: userAddress},
pipeline: [
{$match: {$expr: {$and: [
{ $eq: ["$token_address", "$tokenAddress"] },
{ $eq: ["$address", "$userAddress"] },
]}}],
as: "EthTokenBalance",
}}
];
return query.aggregate(pipeline);
});
lookup管道使用匹配階段來指定其他連接條件。 另外,請注意 let 定義了查找管道要使用的變量。 這是必需的,因為查找管道無法直接訪問原始集合中的屬性。 有關詳細信息,請參閱 MongoDB $lookup 文檔中的“使用 $lookup 指定多個連接條件”部分。
項目管道類似于鍵或選擇、添加或刪除現(xiàn)有字段。
const pipeline = [{ project: { name: 1 } }];
const query = new Moralis.Query("User");
query
.aggregate(pipeline)
.then(function (results) {
// results contains only name field
})
.catch(function (error) {
// There was an error.
});
組管道類似于不同的。
您可以按字段分組:
// score is the field. $ before score lets the database know this is a field
const pipeline = [{ group: { objectId: "$score" } }];
const query = new Moralis.Query("User");
query
.aggregate(pipeline)
.then(function (results) {
// results contains unique score values
})
.catch(function (error) {
// There was an error.
});
您可以應用集體計算,如 $sum、$avg、$max、$min。
// total will be a newly created field to hold the sum of score field
const pipeline = [{ group: { objectId: null, total: { $sum: "$score" } } }];
const query = new Moralis.Query("User");
query
.aggregate(pipeline)
.then(function (results) {
// results contains sum of score field and stores it in results[0].total
})
.catch(function (error) {
// There was an error.
});
如果要對包含數(shù)值但它們作為字符串存儲在數(shù)據庫中的列執(zhí)行計算,則必須將值轉換為數(shù)值數(shù)據類型。 例如,存儲在字符串列中的 uint256 應使用 ?$toLong
? 進行轉換。
{ group: { objectId: '$nftItem', priceOfAllNfts: { $sum: {$toLong : '$price'} } } },
可以使用 ?$$ROOT
? 訪問與分組字段匹配的文檔集合,并且可以使用 ?$push
? 累加器將其推送到數(shù)組中。
// games will be an array of all the games played by each unique player
const pipeline = [
{ group: { objectId: "$playerId", games: { $push: "$ROOT" } } },
];
const query = new Moralis.Query("GameRound");
query
.aggregate(pipeline)
.then(function (results) {
// results contains a collection of players with their respective games played
})
.catch(function (error) {
// There was an error.
});
您可以使用點表示法按子文檔的列進行分組。 但是,您必須將其括在引號中。
{ group: { objectId: '$player.username', games: { $push: "$ROOT" } } },
排序階段用于按給定列按特定順序對結果進行排序。
指定排序順序,1 用于升序排序,-1 用于降序排序。
// This will sort the rows in ascending order based on the username field
{
sort: {
username: 1;
}
}
您可以按給定順序按幾列排序。
// This will sort the rows in ascending order based on the country field,
// and then in descending order on the city field
{ sort : { country: 1, city: -1 } }
跳過階段跳過傳遞到該階段的指定行數(shù)。 這通常在實現(xiàn)分頁功能時使用。
// This stage will skip the first 5 rows passed into this stage
{
skip: 5;
}
限制階段僅包括傳入該階段的前 n 行。
// This stage will throw away all rows except the first 5
{
limit: 5;
}
count 階段返回傳遞到分配給變量名稱的階段的行數(shù)。
// This stage will return the number of rows passed into the stage
// and store it in the variable numberOfNfts
{
count: "numberOfNfts";
}
可以使用 distinct 進行查詢,允許您找到指定字段的唯一值。
?
MasterKey
?是必需的。
const query = new Moralis.Query("User");
query
.distinct("age")
.then(function (results) {
// results contains unique age
})
.catch(function (error) {
// There was an error.
});
您還可以使用 ?equalTo
?限制結果。
const query = new Moralis.Query("User");
query.equalTo("name", "foo");
query
.distinct("age")
.then(function (results) {
// results contains unique age where name is foo
})
.catch(function (error) {
// There was an error.
});
使用 MongoDB 副本集時,您可以使用 ?query.readPreference(readPreference, includeReadPreference, subqueryReadPreference)
? 函數(shù)來選擇將從哪個副本中檢索對象。 ?includeReadPreference
?參數(shù)選擇從哪個副本中檢索包含的指針,而 ?subqueryReadPreference
?參數(shù)選擇子查詢將在哪個副本中運行。 可能的值為 ?PRIMARY
?(默認)、?PRIMARY_PREFERRED
?、?SECONDARY
?、?SECONDARY_PREFERRED
?或 ?NEAREST
?。 如果未傳遞 ?includeReadPreference
?參數(shù),則為 ?readPreference
?選擇的相同副本也將用于包含。 相同的規(guī)則適用于 ?subqueryReadPreference
?參數(shù)。
query.readPreference("SECONDARY", "SECONDARY_PREFERRED", "NEAREST");
更多建議: