带驱动程序的 MongoDB
本页面提供 mongosh 方法的相关信息。要查看 MongoDB 驱动程序中的等效方法,请参阅编程语言的相应页面:
定义
兼容性
此方法可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
注意
所有 MongoDB Atlas 集群都支持此命令。有关 Atlas 对所有命令的支持的信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
find() 方法采用以下形式:
db.collection.find( <query>, <projection>, <options> )
参数
find() 方法使用以下参数:
Parameter | 类型 | 说明 |
|---|---|---|
文档 | 可选。使用查询运算符指定选择筛选器。要返回集合中的所有文档,请省略此参数或传递空文档 ( | |
文档 | 可选。 指定与查询过滤匹配的文档中要返回的字段。 要返回匹配文档中的所有字段,请省略此参数。 有关详细信息,请参阅投影。 | |
文档 | 可选。 为查询指定其他选项。 这些选项可修改查询行为以及结果的返回方式。 有关详细信息,请参阅选项。 |
行为
投射
重要
语言一致性
在调整 find() 和 findAndModify() 投影以便与聚合的 $project 阶段保持一致的过程中:
find()和findAndModify()投影可以接受聚合表达式和语法。MongoDB 对投影执行额外的限制。有关详细信息,请参阅投影限制。
projection 参数确定匹配文档中返回哪些字段。projection 参数采用以下形式的文档:
{ <field1>: <value>, <field2>: <value> ... }
投射 | 说明 |
|---|---|
| 指定包含字段。如果为投影值指定非零整数,则该操作会将该值视为 |
| 指定排除某个字段。 |
| |
| 使用数组投影操作符( 不可用于视图。 |
| 使用 不可用于视图。 |
| 指定投影字段的值。 通过使用聚合表达式和语法(包括使用文本和聚合变量),可以投影新字段或使用新值投影现有字段。
|
选项
选项 | 说明 |
|---|---|
allowDiskUse | 需要超过 100 兆字节的内存来执行的管道是否写入磁盘上的临时文件。有关详细信息,请参阅 |
allowPartialResults | 对于针对分片集合的查询,如果一个或多个查询的分片不可用,则允许该命令(或后续 getMore 命令)返回部分结果,而非错误。 |
awaitData | 如果游标是 tailable-await 游标。要求 |
排序规则 | 更新操作的排序规则设置。 |
comment | 向分析器日志中显示的查询添加 |
解释 | 根据提供的详细程度模式添加解释输出。 |
提示 | 强制查询优化器在查询中使用特定索引。 |
limit | 设置结果集中返回的文档限制。 |
Max | 特定索引的独占上限。 |
maxAwaitTimeMS | 服务器等待新文档以满足可追加游标查询的最长时间。要求 |
maxTimeMS | 服务器应允许查询运行的最长时间(以毫秒为单位)。 |
min | 特定索引的包含下限。 |
noCursorTimeout | 服务器是否应在一段不活动时间(默认 10 分钟)后将游标设置为超时。 |
投影 | |
事务外的 | 指定查询的读关注级别。 |
readPreference | 指定查询的读取偏好级别。 |
returnKey | 是否仅为查询返回索引键。 |
showRecordId | 如果将 |
跳过 | 返回结果集中的第一个文档之前要跳过的文档数量。 |
sort | 结果集中返回的文档的顺序。排序中指定的字段,必须具有索引。 |
可追加 | 指示游标是否可追加。查询的初始结果用尽后,可追加游标将保持打开状态。可追加游标仅适用固定大小集合。 |
嵌入式字段规范
对于嵌入文档中的字段,您可以使用以下任一方式指定字段:
点符号,例如
"field.nestedfield": <value>嵌套表单,例如
{ field: { nestedfield: <value> } }
_id 字段投影
默认情况下,返回的文档中包含 _id 字段,除非您在投影中显式指定 _id: 0 来隐藏该字段。
包括或排除
projection 不能同时包含包含和排除规范,但 _id 字段除外:
在显式包含字段的投影中,
_id字段是您可以显式排除的唯一字段。在明确排除字段的投影中,
_id字段是您可以明确包含的唯一字段;但是,默认情况下包含_id字段。
请参阅投影示例。
排序
当某个操作使用相同字段进行排序和投影时,MongoDB会在应用投影之前对原始字段值进行排序。有关操作顺序的更多信息,请参阅 find() 操作顺序。
Cursor Handling
在 mongosh 中执行 db.collection.find() 会自动迭代游标以显示最多前 20 个文档。输入 it 以继续迭代。
如要使用驱动程序访问返回的文档,请使用该驱动程序语言的相应游标处理机制。
读关注 (read concern)
要指定对 db.collection.find() 的读关注,请使用 cursor.readConcern() 方法。
类型范围
出于比较目的,MongoDB 将某些数据类型视为等效数据类型。对于实例来说,数字类型在比较之前会进行转换。不过,对于大多数数据类型,比较操作符只对目标字段的 BSON 类型与查询操作数的类型相匹配的文档执行比较。考虑以下集合:
{ "_id": "apples", "qty": 5 } { "_id": "bananas", "qty": 7 } { "_id": "oranges", "qty": { "in stock": 8, "ordered": 12 } } { "_id": "avocados", "qty": "fourteen" }
以下查询使用 $gt 来返回其中的 qty 值大于 4 的文档。
db.collection.find( { qty: { $gt: 4 } } )
该查询返回以下文档:
{ "_id": "apples", "qty": 5 } { "_id": "bananas", "qty": 7 }
_id 等于 "avocados" 的文档不会返回,因为其 qty 值的类型为 string,而 $gt 操作数的类型为 integer。
不返回_id等于"oranges"的文档,因为其qty值的类型为object。
注意
要在集合中强制数据类型,请使用模式验证。
会话
对于在一个会话内创建的游标,不能在该会话外调用 getMore。
同样,对于在会话外创建的游标,不能在会话内调用 getMore。
会话空闲超时
MongoDB 驱动程序和 mongosh 将所有操作与服务器会话相关联,未确认的写入操作除外。对于未与会话显式关联的操作(即使用 Mongo.startSession()),MongoDB 驱动程序和 mongosh 会创建隐式会话并将其与该操作关联。
如果会话空闲时间超过 30 分钟,MongoDB Server 会将该会话标记为已过期,并可能随时将其关闭。当 MongoDB Server 关闭会话时,它还会终止任何正在进行的操作并打开与会话关联的游标。这包括使用超过 30 分钟的 noCursorTimeout() 或 maxTimeMS() 配置的游标。
对于空闲时间可能超过 30 分钟的操作,请使用 Mongo.startSession() 将该操作与显式会话关联起来,并使用 refreshSessions 命令定期刷新会话。有关更多信息,请参阅会话空闲超时。
事务
db.collection.find() 可以在分布式事务中使用。
重要
在大多数情况下,与单文档写入操作相比,分布式事务会产生更高的性能成本,并且分布式事务的可用性不应取代有效的模式设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)仍然是数据和使用案例的最佳选择。换言之,对于许多场景,适当的数据建模将最大限度地减少对分布式事务的需求。
有关其他事务使用注意事项(如运行时间限制和 oplog 大小限制),另请参阅生产注意事项。
客户端断开连接
如果发出 db.collection.find() 的客户端在操作完成之前断开连接,MongoDB 会使用 db.collection.find() 将 killOp 标记为终止。
查询设置
8.0版本新增。
您可以使用查询设置来设置索引提示、设置操作拒绝过滤器以及其他字段。这些设置将应用于整个集群上的查询结构。在关闭之后,集群将保留这些设置。
在查询规划期间,查询优化器将使用查询设置作为附加输入,这样会影响为运行查询而选择的计划。您还可以使用查询设置来阻塞查询结构。
要添加查询设置并探索示例,请参阅 setQuerySettings。
您可以为 find、distinct 和 aggregate 命令添加查询设置。
查询设置具有更多功能,相比已弃用的索引过滤器而言是您的首选。
要删除查询设置,请使用 removeQuerySettings。要获取查询设置,请在一个聚合管道中使用一个 $querySettings 阶段。
示例
本节中的示例使用 BIOS 集合中的文档,该集合中的文档通常为如下格式:
{ "_id" : <value>, "name" : { "first" : <string>, "last" : <string> }, // embedded document "birth" : <ISODate>, "death" : <ISODate>, "contribs" : [ <string>, ... ], // Array of Strings "awards" : [ { "award" : <string>, year: <number>, by: <string> } // Array of embedded documents ... ] }
要创建和填充 bios 集合,请参阅 bios 集合。
查找集合中的所有文档
不带参数的 find() 方法返回集合中的所有文档,并返回文档的所有字段。例如,以下操作返回 bios 集合中的所有文档:
db.bios.find()
查找符合查询条件的文件
相等查询
使用操作符查询
要查找符合一组选择条件的文档,请使用 <criteria> 参数调用 find()。
MongoDB 提供各种查询运算符来指定标准。
以下操作使用
$in操作符返回 bios 集合中的文档,其中_id等于5或ObjectId("507c35dd8fada716c89d0013"):db.bios.find( { _id: { $in: [ 5, ObjectId("507c35dd8fada716c89d0013") ] } } ) 以下操作使用
$gt运算符返回bios集合中birth晚于new Date('1950-01-01')的所有文档:db.bios.find( { birth: { $gt: new Date('1950-01-01') } } ) 以下操作使用
$regex操作符返回 BIOS 集合中的文档,其中,name.last字段以字母N开头(或为"LIKE N%")db.bios.find( { "name.last": { $regex: /^N/ } } )
有关查询运算符的列表,请参阅查询谓词。
对范围进行查询
结合比较操作符来指定字段的范围。以下操作从 BIOS 集合文档返回,其中birth位于new Date('1940-01-01')和new Date('1960-01-01')之间(不包括):
db.bios.find( { birth: { $gt: new Date('1940-01-01'), $lt: new Date('1960-01-01') } } )
有关查询运算符的列表,请参阅查询谓词。
多重条件查询
以下操作返回 BIOS 集合中的所有文档,其中 birth 字段为 greater than new Date('1950-01-01'),death 字段不存在:
db.bios.find( { birth: { $gt: new Date('1920-01-01') }, death: { $exists: false } } )
有关查询运算符的列表,请参阅查询谓词。
比较同一文档中的两个字段
$expr 可以包含对同一文档中的字段进行比较的表达式。
创建一个包含这些文档的 monthlyBudget 集合:
db.monthlyBudget.insertMany( [ { _id : 1, category : "food", budget : 400, spent : 450 }, { _id : 2, category : "drinks", budget : 100, spent : 150 }, { _id : 3, category : "clothes", budget : 100, spent : 50 }, { _id : 4, category : "misc", budget : 500, spent : 300 }, { _id : 5, category : "travel", budget : 200, spent : 650 } ] )
以下操作使用 $expr 来查找 spent 金额超过 budget 的文档:
db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )
输出:
{ _id : 1, category : "food", budget : 400, spent : 450 } { _id : 2, category : "drinks", budget : 100, spent : 150 } { _id : 5, category : "travel", budget : 200, spent : 650 }
查询嵌入式文档
以下示例查询 bios 集合中的 name 嵌入式字段。
查询嵌入文档的精确匹配项
以下操作返回 BIOS 集合 中的文档,其中嵌入式文档 name 恰好 是 { first: "Yukihiro", last: "Matsumoto" },包括顺序:
db.bios.find( { name: { first: "Yukihiro", last: "Matsumoto" } } )
name 字段必须与嵌入式文档完全匹配。该查询与具有以下 name 字段的文档不匹配:
{ first: "Yukihiro", aka: "Matz", last: "Matsumoto" } { last: "Matsumoto", first: "Yukihiro" }
嵌入式文档的查询字段
以下操作返回 BIOS 集合中的文档,其中嵌入文档 name 包含值为 "Yukihiro" 的字段 first 和值为 last 的字段 "Matsumoto"。查询使用点符号访问嵌入文档中的字段:
db.bios.find( { "name.first": "Yukihiro", "name.last": "Matsumoto" } )
该查询与文档相匹配,其中,name 字段包含嵌入式文档,字段 first 的值为 "Yukihiro",字段 last 的值为 "Matsumoto"。例如,查询将匹配包含的 name 字段为以下任一值的文档:
{ first: "Yukihiro", aka: "Matz", last: "Matsumoto" } { last: "Matsumoto", first: "Yukihiro" }
有关更多信息和示例,另请参阅针对嵌入式/嵌套文档的查询。
查询数组
查询数组元素
以下示例查询 bios 集合中的 contribs 数组。
以下操作返回 bios 集合中的文档,其中,数组字段
contribs包含元素"UNIX":db.bios.find( { contribs: "UNIX" } ) 以下操作返回 bios 集合中的文档,其中,数组字段
contribs包含元素"ALGOL"或"Lisp":db.bios.find( { contribs: { $in: [ "ALGOL", "Lisp" ]} } ) 以下操作使用
$all查询操作符返回 BIOS 集合中的文档,其中数组字段contribs同时包含元素"ALGOL"和"Lisp":db.bios.find( { contribs: { $all: [ "ALGOL", "Lisp" ] } } ) 请参阅
$all,查看更多示例。另请参阅$elemMatch。以下操作使用
$size操作符返回 BIOS 集合中的文档,其中contribs的数组大小为 4:db.bios.find( { contribs: { $size: 4 } } )
有关查询数组的更多信息和示例,请参阅:
有关大量特定查询运算符的列表,请参阅数组查询谓词运算符。
查询文档数组
以下示例查询 bios 集合中的 awards 数组。
以下操作返回 BIOS 集合中的文档,其中
awards数组包含一个award字段等于"Turing Award"的元素:db.bios.find( { "awards.award": "Turing Award" } ) 以下操作返回 bios 集合中的文档,其中
awards数组至少包含一个元素,award字段等于"Turing Award",且year字段大于 1980:db.bios.find( { awards: { $elemMatch: { award: "Turing Award", year: { $gt: 1980 } } } } ) 使用
$elemMatch操作符可在一个数组元素上指定多个条件。
有关查询数组的更多信息和示例,请参阅:
有关大量特定查询运算符的列表,请参阅数组查询谓词运算符。
查询BSON正则表达式
要查找包含BSON正则表达式作为值的文档,请调用find()并将bsonRegExp选项设立为true 。 bsonRegExp选项允许您返回无法表示为JavaScript正则表达式的正则表达式。
以下操作返回名为 testbson 的集合中的文档,其中名为 foo 的字段的值是 BSONRegExp 类型:
db.testbson.find( {}, {}, { bsonRegExp: true } )
[ { _id: ObjectId('65e8ba8a4b3c33a76e6cacca'), foo: BSONRegExp('(?-i)AA_', 'i') } ]
投影
投影参数指定要返回的字段。该参数包括包含或排除规范,但不能同时包括两者,除非排除是针对 _id 字段。
注意
除非在投影文档 _id: 0 中显式排除 _id 字段,否则将返回 _id 字段。
指定待返回的字段
以下操作会查找 bios 集合中的所有文档,并仅返回 name 字段、contribs 字段和 _id 字段:
db.bios.find( { }, { name: 1, contribs: 1 } )
注意
除非在投影文档 _id: 0 中显式排除 _id 字段,否则将返回 _id 字段。
显式排除的字段
以下操作查询 BIOS 集合并返回除name嵌入式文档中的first字段和birth字段之外的所有字段:
db.bios.find( { contribs: 'OOP' }, { 'name.first': 0, birth: 0 } )
显式排除 _id 字段
注意
除非在投影文档 _id: 0 中显式排除 _id 字段,否则将返回 _id 字段。
以下操作会在 bios 集合中查找文档,并仅返回 name 字段和 contribs 字段:
db.bios.find( { }, { name: 1, contribs: 1, _id: 0 } )
关于数组和嵌入式文档
以下操作查询 BIOS 集合并返回 name 嵌入文档中的 last 字段和 contribs 数组中的前两个元素:
db.bios.find( { }, { _id: 0, 'name.last': 1, contribs: { $slice: 2 } } )
您还可以使用嵌套形式指定嵌入式字段。例如:
db.bios.find( { }, { _id: 0, name: { last: 1 }, contribs: { $slice: 2 } } )
使用聚合表达式
db.collection.find() 投影可以接受 聚合表达式和语法。
使用聚合表达式和事务语法,您可以投影新字段或使用新值投影现有字段。例如,以下操作使用聚合表达式来重写 name 和 awards 字段的值,并纳入新字段 reportDate、reportBy 和 reportNumber。
db.bios.find( { }, { _id: 0, name: { $concat: [ { $ifNull: [ "$name.aka", "$name.first" ] }, " ", "$name.last" ] }, birth: 1, contribs: 1, awards: { $cond: { if: { $isArray: "$awards" }, then: { $size: "$awards" }, else: 0 } }, reportDate: { $dateToString: { date: new Date(), format: "%Y-%m-%d" } }, reportBy: "hellouser123", reportNumber: { $literal: 1 } } )
要将 reportRun 字段设置为值 1,该操作返回以下文档:
{ "birth" : ISODate("1924-12-03T05:00:00Z"), "contribs" : [ "Fortran", "ALGOL", "Backus-Naur Form", "FP" ], "name" : "John Backus", "awards" : 4, "reportDate" : "2020-06-05", "reportBy" : "hellouser123", "reportNumber" : 1 } { "birth" : ISODate("1927-09-04T04:00:00Z"), "contribs" : [ "Lisp", "Artificial Intelligence", "ALGOL" ], "name" : "John McCarthy", "awards" : 3, "reportDate" : "2020-06-05", "reportBy" : "hellouser123", "reportNumber" : 1 } { "birth" : ISODate("1906-12-09T05:00:00Z"), "contribs" : [ "UNIVAC", "compiler", "FLOW-MATIC", "COBOL" ], "name" : "Grace Hopper", "awards" : 4, "reportDate" : "2020-06-05", "reportBy" : "hellouser123", "reportNumber" : 1 } { "birth" : ISODate("1926-08-27T04:00:00Z"), "contribs" : [ "OOP", "Simula" ], "name" : "Kristen Nygaard", "awards" : 3, "reportDate" : "2020-06-05", "reportBy" : "hellouser123", "reportNumber" : 1 } { "birth" : ISODate("1931-10-12T04:00:00Z"), "contribs" : [ "OOP", "Simula" ], "name" : "Ole-Johan Dahl", "awards" : 3, "reportDate" : "2020-06-05", "reportBy" : "hellouser123", "reportNumber" : 1 } { "birth" : ISODate("1956-01-31T05:00:00Z"), "contribs" : [ "Python" ], "name" : "Guido van Rossum", "awards" : 2, "reportDate" : "2020-06-05", "reportBy" : "hellouser123", "reportNumber" : 1 } { "birth" : ISODate("1941-09-09T04:00:00Z"), "contribs" : [ "UNIX", "C" ], "name" : "Dennis Ritchie", "awards" : 3, "reportDate" : "2020-06-05", "reportBy" : "hellouser123", "reportNumber" : 1 } { "birth" : ISODate("1965-04-14T04:00:00Z"), "contribs" : [ "Ruby" ], "name" : "Matz Matsumoto", "awards" : 1, "reportDate" : "2020-06-05", "reportBy" : "hellouser123", "reportNumber" : 1 } { "birth" : ISODate("1955-05-19T04:00:00Z"), "contribs" : [ "Java" ], "name" : "James Gosling", "awards" : 2, "reportDate" : "2020-06-05", "reportBy" : "hellouser123", "reportNumber" : 1 } { "contribs" : [ "Scala" ], "name" : "Martin Odersky", "awards" : 0, "reportDate" : "2020-06-05", "reportBy" : "hellouser123", "reportNumber" : 1 }
迭代返回的游标
在 mongosh 中,如果未使用 var 关键字将返回的游标分配给变量,则该游标将自动迭代,最多可访问与查询匹配的前 20 个文档。可以更新 displayBatchSize 变量来更改自动迭代文档的数量。
以下示例将批处理大小设置为 3。未来 db.collection.find() 操作每次游标遍历仅返回 3 份文档。
config.set( "displayBatchSize", 3 )
如需手动遍历结果,请将返回的游标分配给带有 var 关键字的变量,如以下部分所示。
使用变量名称
以下示例使用变量 myCursor 迭代游标并打印匹配的文档:
var myCursor = db.bios.find( ); myCursor
使用 next() 方法
以下示例使用游标方法 next() 访问文档:
var myCursor = db.bios.find( ); var myDocument = myCursor.hasNext() ? myCursor.next() : null; if (myDocument) { var myName = myDocument.name; print (tojson(myName)); }
要打印,您还可以使用 printjson() 方法而不是 print(tojson()):
if (myDocument) { var myName = myDocument.name; printjson(myName); }
使用 forEach() 方法
以下示例使用游标方法 forEach() 遍历游标并访问文档:
var myCursor = db.bios.find( ); myCursor.forEach(printjson);
修改游标行为
mongosh 和驱动程序 提供几种游标方法,这些方法调用 find() 方法返回的游标来修改其行为。
为结果集中的文档排序
sort() 方法对结果集中的文档排序。以下操作返回 bios 集合中按 name 字段升序排序的文档:
db.bios.find().sort( { name: 1 } )
sort() 相当于 SQL 中的 ORDER BY 语句。
限制要返回的文档数量
limit() 方法限制结果集中的文档数量。以下操作最多返回 biaos 集合中的 5 个文档:
db.bios.find().limit( 5 )
limit() 相当于 SQL 中的 LIMIT 语句。
设置结果集的启动点
skip() 方法控制结果集的起点。以下操作会跳过 bios 集合中的前 5 份文档并返回所有剩余文档:
db.bios.find().skip( 5 )
指定排序规则。
排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。
collation() 方法指定了 db.collection.find() 操作的排序规则。
db.bios.find( { "name.last": "hopper" } ).collation( { locale: "en_US", strength: 1 } )
组合游标方法
db.bios.find().sort( { name: 1 } ).limit( 5 ) db.bios.find().limit( 5 ).sort( { name: 1 } )
这两个语句是等效的;也就是说,链接 limit() 和 sort() 方法的顺序并不重要。 两个语句均返回前五个文档,由“名称”的升序排序决定。
可用的 mongosh 游标方法
在 let 选项中使用变量
您可以指定查询选项来修改查询行为并指示如何返回结果。
例如,要定义可在 find 方法中的其他位置访问的变量,请使用 let 选项。要使用变量过滤结果,必须在 $expr 操作符中访问该变量。
创建集合 cakeFlavors:
db.cakeFlavors.insertMany( [ { _id: 1, flavor: "chocolate" }, { _id: 2, flavor: "strawberry" }, { _id: 3, flavor: "cherry" } ] )
以下示例在 let 中定义了一个 targetFlavor 变量,并使用该变量检索巧克力蛋糕口味:
db.cakeFlavors.find( { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } }, { _id: 0 }, { let : { targetFlavor: "chocolate" } } )
输出:
[ { flavor: 'chocolate' } ]
检索授予当前用户的角色相关的文档
从 MongoDB 7.0 开始,您可以使用新的 USER_ROLES 系统变量来返回用户角色。
本部分的场景显示了具有各种角色的用户,而这些用户对包含预算信息的集合中的文档具有有限访问权限。
该场景显示了 USER_ROLES 的一种可能用途。budget 集合包含带有名为 allowedRoles 字段的文档。正如以下场景所示,您可以编写查询将 allowedRoles 字段中找到的用户角色与 USER_ROLES 系统变量返回的角色进行比较。
注意
有关另一个 USER_ROLES 示例场景,请参阅检索授予当前用户的角色相关的医疗信息。该示例不会将用户角色存储在文档字段中,如以下示例所示。
对于本部分中的预算方案,请执行以下步骤来创建角色、用户和 budget 集合:
创建用户
创建名为 John 和 Jane 的用户,并赋予所需角色。将 test 数据库替换为您的数据库名称。
db.createUser( { user: "John", pwd: "jn008", roles: [ { role: "Marketing", db: "test" }, { role: "Development", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ] } ) db.createUser( { user: "Jane", pwd: "je009", roles: [ { role: "Sales", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ] } )
创建集合
运行:
db.budget.insertMany( [ { _id: 0, allowedRoles: [ "Marketing" ], comment: "For marketing team", yearlyBudget: 15000 }, { _id: 1, allowedRoles: [ "Sales" ], comment: "For sales team", yearlyBudget: 17000, salesEventsBudget: 1000 }, { _id: 2, allowedRoles: [ "Operations" ], comment: "For operations team", yearlyBudget: 19000, cloudBudget: 12000 }, { _id: 3, allowedRoles: [ "Development" ], comment: "For development team", yearlyBudget: 27000 } ] )
执行以下步骤以检索 John 可以访问的文档:
检索文档
要使用系统变量,请将$$添加到变量名称的开头。将USER_ROLES系统变量指定为$$USER_ROLES。
运行:
db.budget.find( { $expr: { $not: { $eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ] } } } )
上一示例从budget集合中返回至少与运行该示例的用户所具有的角色之一匹配的文档。为此,该示例使用$setIntersection返回文档,其中budget文档allowedRoles字段与$$USER_ROLES的用户角色集之间的交集不为空。
检查文档
John 具有Marketing、Operations和Development 角色,且能看到以下文档:
[ { _id: 0, allowedRoles: [ 'Marketing' ], comment: 'For marketing team', yearlyBudget: 15000 }, { _id: 2, allowedRoles: [ 'Operations' ], comment: 'For operations team', yearlyBudget: 19000, cloudBudget: 12000 }, { _id: 3, allowedRoles: [ 'Development' ], comment: 'For development team', yearlyBudget: 27000 } ]
执行以下步骤以检索 Jane 可以访问的文档:
检查文档
Jane 具有 Sales和 Operations 角色,且能看到以下文档:
[ { _id: 1, allowedRoles: [ 'Sales' ], comment: 'For sales team', yearlyBudget: 17000, salesEventsBudget: 1000 }, { _id: 2, allowedRoles: [ 'Operations' ], comment: 'For operations team', yearlyBudget: 19000, cloudBudget: 12000 } ]
注意
在分片集群上,查询可以由另一个服务器节点代表用户在分片上运行。在这些查询中,USER_ROLES 仍填充用户的角色。
使用选项修改查询
以下示例显示如何在 find() 查询中使用 options 字段。使用以下 insertMany() 设置 users 集合:
db.users.insertMany( [ { username: "david", age: 27 }, { username: "amanda", age: 25 }, { username: "rajiv", age: 32 }, { username: "rajiv", age: 90 } ] )
限制和选项
以下查询使用 limit 选项参数限制结果集中的文档数:
db.users.find( { username : "rajiv"}, // query { age : 1 }, // projection { limit : 1 } // options )
allowDiskUse 及其选项
以下查询使用 options 参数启用 allowDiskUse:
db.users.find( { username : "david" }, { age : 1 }, { allowDiskUse : true } )
解释和选项
以下查询使用 options 参数获取 executionStats 解释输出:
var cursor = db.users.find( { username: "amanda" }, { age : 1 }, { explain : "executionStats" } ) cursor.next()
在查询中指定多个选项
以下查询在单个查询中使用多个 options。此查询使用设置为 2 的 limit 来仅返回两个文档,并使用设置为 true 的 showRecordId 来返回文档在结果集中的位置:
db.users.find( {}, { username: 1, age: 1 }, { limit: 2, showRecordId: true } )