Moralis 查询
我们已经看到了带有 get
的 Moralis.Query
如何从 Moralis 中检索单个 Moralis.Object
。 还有许多其他方法可以使用 Moralis.Query
检索数据。 您可以一次检索多个对象,对要检索的对象设置条件等等。
基本查询
在许多情况下,get
功能不足以指定要检索的对象。 Moralis.Query
提供了不同的方法来检索对象列表,而不仅仅是单个对象。
一般模式是创建一个 Moralis.Query
,在其上设置条件,然后使用 find
检索匹配的 Moralis.Objects
数组。 例如,要检索具有特定 ownerName
的monster,请使用 equalTo
方法来约束键的值。
你可以使用JS
、React
、Unity
来实现
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
}
}
使用主密钥
在某些情况下,查询需要主密钥,
例如,如果您想获取所有用户的列表,您只能使用主密钥在云功能中执行此操作 - 因为由于 ACL,用户无法读取其他用户的信息。
query.find({ useMasterKey: true });
查询约束
有几种方法可以对 Moralis.Query
找到的对象施加约束。 您可以使用 notEqualTo
过滤掉具有特定键值对的对象:
query.notEqualTo("ownerName", "Daenerys");
您可以提供多个约束,并且对象只有在匹配所有约束时才会出现在结果中。 换句话说,它就像约束的 AND
。
query.notEqualTo("ownerName", "Daenerys");
query.greaterThan("ownerAge", 18);
您可以通过设置限制来限制结果的数量。 默认情况下,结果限制为 100。在旧的 Moralis 托管后端中,最大限制为 1,000,但 Moralis Dapps 现在删除了该限制:
query.limit(10); // limit to at most 10 results
如果您只想要一个结果,更方便的替代方法可能是使用first
而不是使用 find
(可以通过JS
、React
实现)。
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 现在取消了该限制。 这对于分页很有用:
query.skip(10); // skip the first 10 results
获取满足您查询的表中的总行数,例如 分页目的 - 您可以使用 withCount
。
注意:启用此标志将更改响应的结构,请参见下面的示例。
示例 - 假设您在名为 Monster 的表中有 200 行(可以通过JS
、React
实现):
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
操作可能会很慢而且很昂贵。
如果您只想获取没有对象的计数 - 使用Counting Objects。
要对数字和字符串等可排序类型进行排序,您可以控制返回结果的顺序:
// 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
,提供可接受值的数组。 这对于用单个查询替换多个查询通常很有用。
例如 - 如果您想检索特定列表中任何monster所有者拥有的monster:
// Finds monsters from any of Jonathan, Dario, or Shawn
query.containedIn("ownerName", [
"Jonathan Walsh",
"Dario Wunsch",
"Shawn Simon",
]);
要检索与多个值中的任何一个都不匹配的对象,您可以使用 notContainedIn
,提供一个可接受值的数组。
例如,如果您想从列表中的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
方法。
例如,如果您有一个包含运动队的类,并且您在用户类中存储了用户的家乡,则可以发出一次查询以查找家乡球队有获胜记录的用户列表。 查询将如下所示:
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
。 例如,查找家乡球队有输球记录的用户:
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
来实现
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
来实现):
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
为小写。
数组值查询
对于数组类型的键,您可以通过以下方式找到键的数组值包含 2 的对象:
// Find objects where the array in arrayKey contains 2.
query.equalTo("arrayKey", 2);
您还可以找到键的数组值包含每个元素 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
关键字而不是 Moralis - 即新
Parse.Query("EthTokenTransfers")
- 这可能会在未来的版本中得到修复(Moralis 是 Parse 的一个分支)。
- 不要在查询中转义
$
。 - 您可以使用主密钥 -
const results = query.find({ useMasterKey: true })
可以通过单击“保存”在会话之间保存代码。
字符串值查询
从搜索开始
使用 startsWith
限制以特定字符串开头的字符串值。 与 MySQL LIKE 运算符类似,这是索引的,因此对于大型数据集很有效:
// 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 限制在任何给定时间可以在特定应用程序上运行的操作数。
全文检索
使用全文以获得高效的搜索功能。 文本索引会自动为您创建。 您的字符串将转换为标记以进行快速搜索。
注意:全文搜索可能是资源密集型的。 确保使用索引的成本物有所值。
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.
});
关系查询
有几种方法可以发出对关系数据的查询。 要检索字段与特定 Moralis.Object
匹配的对象,您可以使用 equalTo
,就像其他数据类型一样。
例如,如果每个 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
。 为了查找包含图片的帖子的评论,您可以执行以下操作:
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
。 要查找没有图片的帖子的评论,您可以执行以下操作:
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
来发出包含多个字段的查询。 此功能也适用于 Moralis.Query
助手,例如 first
和 get
。
计数对象
注意:在旧的 Moralis 托管后端中,计数查询的速率被限制为每分钟最多 160 个请求。 他们还为包含 1,000 多个对象的类返回了不准确的结果。 但是,Moralis Dapp 已经消除了这两个限制,并且可以计算远高于 1,000 个的对象。
要计算有多少对象与查询匹配,但您不需要检索所有匹配的对象,可以使用 count
而不是 find
。
例如,要计算特定monster
拥有者拥有的monster
数量:
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
)。
OR-ed 查询约束
要查找与多个查询之一匹配的对象,您可以使用 Moralis.Query.or
方法构造一个查询,该查询是传入查询的 OR
。
例如,如果您想找到获得很多胜利或少数胜利的玩家,您可以执行以下操作:
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.
});
AND-ed 查询约束
要查找符合所有条件的对象,通常只使用一个查询。 您可以向新创建的 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 岁且没有朋友或至少有两个朋友的用户,您可以执行以下操作:
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
是必需的。
聚合使用阶段通过将结果从一个阶段传递到下一个阶段来过滤结果。 前一阶段的输出成为下一阶段的输入。
您可以使用数组或对象创建管道。
const pipelineObject = {
group: { objectId: "$name" },
};
const pipelineArray = [{ group: { objectId: "$name" } }];
有关可用阶段的列表,请参阅 Mongo 聚合文档。
注意:Mongo 聚合文档中的大多数操作都适用于
Moralis Server
,但 _id
不存在。 请替换为 objectId
。
Match
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 (Join)
lookup管道类似于 SQL 中的 LEFT OUTER JOIN。 它将匹配另一个集合中的文档并将它们作为数组属性带入结果中。
例如,在投资组合应用程序中,您可能希望显示用户的所有代币交易。 在 Moralis 中,这些存储在 EthTokenTransfers
集合中。 除了令牌名称和小数位数之外,此集合包含所需的所有信息,这些信息是在前端以一种很好的方式显示此信息所必需的。 额外的信息在 EthTokenBalance
集合中,为了得到它,我们需要查找。 有关更多详细信息,请查看 Mongo lookup文档。
简单查找(单等式)
不幸的是,对于我们的用例,EthTokenBalance
集合不仅包含我们当前用户的信息,还包含所有用户的信息。 这意味着每个持有该令牌的用户都会重复该令牌名称。 这意味着加入多个属性,它需要不同的语法,下面将介绍。 现在,假设我们有另一个名为 Token
的集合,它看起来像这样:
Token {
objectId: string,
token_address: string,
symbol: string,
name: string,
decimals: number
}
然后你会定义一个这样的云函数(聚合查询必须在云代码中运行)。
记住要像
\$
一样转义 $
以防止解析错误(现在已修复!)。
// 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
表中匹配文档的输出数组的名称。 如果连接是一对多而不是一对一,则此数组的长度将大于 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 指定多个连接条件”部分。
项目(选择)
项目管道类似于键或选择、添加或删除现有字段。
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.
});
Group
组管道类似于不同的。
您可以按字段分组:
// 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.
});
如果要对包含数值但它们作为字符串存储在数据库中的列执行计算,则必须将值转换为数值数据类型。 例如,存储在字符串列中的 uint256 应使用 $toLong
进行转换。
{ group: { objectId: '$nftItem', priceOfAllNfts: { $sum: {$toLong : '$price'} } } },
可以使用 $$ROOT
访问与分组字段匹配的文档集合,并且可以使用 $push
累加器将其推送到数组中。
// 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" } } },
Sort
排序阶段用于按给定列按特定顺序对结果进行排序。
指定排序顺序,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 } }
skip
跳过阶段跳过传递到该阶段的指定行数。 这通常在实现分页功能时使用。
// This stage will skip the first 5 rows passed into this stage
{
skip: 5;
}
Limit
限制阶段仅包括传入该阶段的前 n 行。
// This stage will throw away all rows except the first 5
{
limit: 5;
}
Count
count 阶段返回传递到分配给变量名称的阶段的行数。
// This stage will return the number of rows passed into the stage
// and store it in the variable numberOfNfts
{
count: "numberOfNfts";
}
Distinct
可以使用 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)
函数来选择将从哪个副本中检索对象。 includeReadPreference
参数选择从哪个副本中检索包含的指针,而 subqueryReadPreference
参数选择子查询将在哪个副本中运行。 可能的值为 PRIMARY
(默认)、PRIMARY_PREFERRED
、SECONDARY
、SECONDARY_PREFERRED
或 NEAREST
。 如果未传递 includeReadPreference
参数,则为 readPreference
选择的相同副本也将用于包含。 相同的规则适用于 subqueryReadPreference
参数。
query.readPreference("SECONDARY", "SECONDARY_PREFERRED", "NEAREST");