db.collection.find()
带驱动程序的 MongoDB
本页面提供 mongosh
方法的相关信息。要查看 MongoDB 驱动程序中的等效方法,请参阅编程语言的相应页面:
定义
兼容性
此方法可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
重要
此命令在 M 0 、 M 2和 M 5集群中提供有限支持。 有关更多信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
find()
方法采用以下形式:
db.collection.find( <query>, <projection>, <options> )
find()
方法使用以下参数:
行为
投射
重要
语言一致性
在调整 find()
和 findAndModify()
投影以便与聚合的 $project
阶段保持一致的过程中:
find()
和findAndModify()
投影可以接受聚合表达式和语法。MongoDB 对投影执行额外的限制。有关详细信息,请参阅投影限制。
projection
参数确定匹配文档中返回哪些字段。projection
参数采用以下形式的文档:
{ <field1>: <value>, <field2>: <value> ... }
投射 | 说明 |
---|---|
<field>: <1 or true> | 指定包含字段。如果为投影值指定非零整数,则该操作会将该值视为 true 。 |
<field>: <0 or false> | 指定排除某个字段。 |
"<field>.$": <1 or true> | |
<field>: <array projection> | 使用数组投影操作符( 不可用于视图。 |
<field>: <$meta expression> | 使用 不可用于视图。 |
<field>: <aggregation expression> | 指定投影字段的值。 通过使用聚合表达式和语法(包括使用文本和聚合变量),可以投影新字段或使用新值投影现有字段。
|
选项
选项 | 说明 |
---|---|
allowDiskUse | 需要超过 100 兆字节的内存来执行的管道是否写入磁盘上的临时文件。有关详细信息,请参阅 cursor.allowDiskUse() 。 |
allowPartialResults | 对于针对分片集合的查询,如果一个或多个查询的分片不可用,则允许该命令(或后续 getMore 命令)返回部分结果,而非错误。 |
awaitData | 如果游标是 tailable-await 游标。要求 tailable 为true 。 |
排序规则 | 更新操作的排序规则设置。 |
comment | 向分析器日志中显示的查询添加 $comment 。 |
解释 | 根据提供的详细程度模式添加解释输出。 |
提示 | 强制查询优化器在查询中使用特定索引。 |
limit | 设置结果集中返回的文档限制。 |
Max | 特定索引的独占上限。 |
maxAwaitTimeMS | 服务器等待新文档以满足可追加游标查询的最长时间。要求 tailable 和 awaitData 为 true 。 |
maxTimeMS | 服务器应允许查询运行的最长时间(以毫秒为单位)。 |
min | 特定索引的包含下限。 |
noCursorTimeout | 服务器是否应在一段不活动时间(默认 10 分钟)后将游标设置为超时。 |
事务外的 | 指定查询的读关注级别。 |
readPreference | 指定查询的读取偏好级别。 |
returnKey | 是否仅为查询返回索引键。 |
showRecordId | 如果将 $recordId 字段添加到返回的文档中。$recordId 表示文档在结果集中的位置。 |
跳过 | 返回结果集中的第一个文档之前要跳过的文档数量。 |
sort | 结果集中返回的文档的顺序。排序中指定的字段,必须具有索引。 |
可追加 | 指示游标是否可追加。查询的初始结果用尽后,可追加游标将保持打开状态。可追加游标仅适用固定大小集合。 |
嵌入式字段规范
对于嵌入文档中的字段,您可以使用以下任一方式指定字段:
点符号,例如
"field.nestedfield": <value>
嵌套表单,例如
{ field: { nestedfield: <value> } }
_id
字段投影
默认情况下,返回的文档中包含 _id
字段,除非您在投影中显式指定 _id: 0
来隐藏该字段。
包括或排除
projection
不能同时包含包含和排除规范,但 _id
字段除外:
在显式包含字段的投影中,
_id
字段是您可以显式排除的唯一字段。在明确排除字段的投影中,
_id
字段是您可以明确包含的唯一字段;但是,默认情况下包含_id
字段。
请参阅投影示例。
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 大小限制),另请参阅生产注意事项。
客户端断开连接
从 MongoDB 4.2 开始,如果在操作完成之前,发出 db.collection.find()
的客户端断开连接,MongoDB 将使用killOp
将 db.collection.find()
标记为终止。
查询设置
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 } )
显式排除 字段<a class=\" \" href=\" \" title=\" \"><svg xmlns=\" \" width=\" \" height=\" \" fill=\" \" viewbox=\" \" class=\" \"_id
role=\" \" aria-label=\" \"><path fill=\" \" d=\" \"> <path fill=\" \" d=\" \">
注意
除非在投影文档 _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
使用 方法<a class=\" \" href=\" \"next()
title=\" \"><svg xmlns=\" \" width=\" \" height=\" \" fill=\" \" viewbox=\" \" class=\" \" role=\" \" aria-label=\" \"><path fill=\" \" d=\" \"> <path fill=\" \" d=\" \">
以下示例使用游标方法 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); }
使用 方法<a class=\" \" href=\" \"forEach()
title=\" \"><svg xmlns=\" \" width=\" \" height=\" \" fill=\" \" viewbox=\" \" class=\" \" role=\" \" aria-label=\" \"><path fill=\" \" d=\" \"> <path fill=\" \" d=\" \">
以下示例使用游标方法 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
选项中使用变量<a class=\" \" href=\" \" title=\" \"><svg xmlns=\" \" width=\" \" height=\" \" fill=\" \" viewbox=\" \" class=\" \" role=\" \" aria-label=\" \"><path fill=\" \" d=\" \"> <path fill=\" \" d=\" \">
您可以指定查询选项来修改查询行为并指示如何返回结果。
例如,要定义可在 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 } )