Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

db.collection.find()

在此页面上

  • 定义
  • 兼容性
  • 语法
  • 行为
  • 示例
  • 了解详情

带驱动程序的 MongoDB

本页面提供 mongosh 方法的相关信息。要查看 MongoDB 驱动程序中的等效方法,请参阅编程语言的相应页面:

C#Java SyncNode.jsPyMongoCC++GoJava RSKotlin CoroutineKotlin SyncPHPMongoidRustScala
db.collection.find(query, projection, options)

选择集合或视图中的文档,并返回指向所选文档的游标

返回:指向与 query 条件匹配的文档的游标。当 find() 方法“返回文档”时,实际上是返回一个指向文档的游标。

此方法可用于以下环境中托管的部署:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

重要

此命令在 M 0 、 M 2和 M 5集群中提供有限支持。 有关更多信息,请参阅不支持的命令。

find() 方法采用以下形式:

db.collection.find( <query>, <projection>, <options> )

find() 方法使用以下参数:

Parameter
类型
说明
文档

可选。使用查询运算符指定选择筛选器。要返回集合中的所有文档,请省略此参数或传递空文档 ({})。

文档

可选。指定与查询过滤器匹配的文档中要返回的字段。要返回匹配文档中的所有字段,请忽略此参数。有关详细信息,请参阅 投影。

文档

可选。指定查询的附加选项。这些选项可修改查询行为以及返回结果的方式。有关详细信息,请参阅选项。

重要

语言一致性

在调整 find()findAndModify() 投影以便与聚合的 $project 阶段保持一致的过程中:

projection 参数确定匹配文档中返回哪些字段。projection 参数采用以下形式的文档:

{ <field1>: <value>, <field2>: <value> ... }
投射
说明
<field>: <1 or true>
指定包含字段。如果为投影值指定非零整数,则该操作会将该值视为true
<field>: <0 or false>
指定排除某个字段。
"<field>.$": <1 or true>

使用 $ 数组投影操作符返回与数组字段的查询条件匹配的第一个元素。如果您为该投影值指定非零整数,则该操作会将该值视为 true

不可用于视图。

<field>: <array projection>

使用数组投影操作符($elemMatch$slice)指定要包含的数组元素。

不可用于视图。

<field>: <$meta expression>

使用 $meta 操作符表达式可指定包含可用的 per-document metadata

不可用于视图。

<field>: <aggregation expression>

指定投影字段的值。

通过使用聚合表达式和语法(包括使用文本和聚合变量),可以投影新字段或使用新值投影现有字段。

  • 如果您为投影值指定非数字、非布尔文字(例如文字字符串、数量或操作符表达式),则该字段将使用新值进行投影,例如:

    • { field: [ 1, 2, 3, "$someExistingField" ] }

    • { field: "New String Value" }

    • { field: { status: "Active", total: { $sum: "$existingArray" } } }

  • 要投影字段的字面值,请使用 $literal 聚合表达式;例如:

    • { field: { $literal: 5 } }

    • { field: { $literal: true } }

    • { field: { $literal: { fieldWithValue0: 0, fieldWithValue1: 1 } } }

选项
说明
allowDiskUse
需要超过 100 兆字节的内存来执行的管道是否写入磁盘上的临时文件。有关详细信息,请参阅 cursor.allowDiskUse()
allowPartialResults
对于针对分片集合的查询,如果一个或多个查询的分片不可用,则允许该命令(或后续 getMore 命令)返回部分结果,而非错误。
awaitData
如果游标是 tailable-await 游标。要求 tailabletrue
排序规则
更新操作的排序规则设置。
comment
向分析器日志中显示的查询添加 $comment
解释
根据提供的详细程度模式添加解释输出。
提示
强制查询优化器在查询中使用特定索引。
limit
设置结果集中返回的文档限制。
Max
特定索引的独占上限。
maxAwaitTimeMS
服务器等待新文档以满足可追加游标查询的最长时间。要求 tailableawaitDatatrue
maxTimeMS
服务器应允许查询运行的最长时间(以毫秒为单位)。
min
特定索引的包含下限。
noCursorTimeout
服务器是否应在一段不活动时间(默认 10 分钟)后将游标设置为超时。
事务外的
指定查询的读关注级别。
readPreference
指定查询的读取偏好级别。
returnKey
是否仅为查询返回索引键。
showRecordId
如果将 $recordId 字段添加到返回的文档中。$recordId 表示文档在结果集中的位置。
跳过
返回结果集中的第一个文档之前要跳过的文档数量。
sort
结果集中返回的文档的顺序。排序中指定的字段,必须具有索引。
可追加
指示游标是否可追加。查询的初始结果用尽后,可追加游标将保持打开状态。可追加游标仅适用固定大小集合

对于嵌入文档中的字段,您可以使用以下任一方式指定字段:

  • 点符号,例如 "field.nestedfield": <value>

  • 嵌套表单,例如 { field: { nestedfield: <value> } }

默认情况下,返回的文档中包含 _id 字段,除非您在投影中显式指定 _id: 0 来隐藏该字段。

projection 不能同时包含包含和排除规范,但 _id 字段除外:

  • 显式包含字段的投影中,_id 字段是您可以显式排除的唯一字段。

  • 明确排除字段的投影中,_id字段是您可以明确包含的唯一字段;但是,默认情况下包含_id字段。

请参阅投影示例。

mongosh 中执行 db.collection.find() 会自动迭代游标以显示最多前 20 个文档。输入 it 以继续迭代。

如要使用驱动程序访问返回的文档,请使用该驱动程序语言的相应游标处理机制。

提示

另请参阅:

要指定对 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() 可以在分布式事务中使用。

  • 对于在 ACID 事务外部创建的游标,无法在 ACID 事务内部调用 getMore

  • 对于在事务中创建的游标,无法在事务外部调用 getMore

重要

在大多数情况下,与单文档写入操作相比,分布式事务会产生更高的性能成本,并且分布式事务的可用性不应取代有效的模式设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)仍然是数据和使用案例的最佳选择。换言之,对于许多场景,适当的数据建模将最大限度地减少对分布式事务的需求。

有关其他事务使用注意事项(如运行时间限制和 oplog 大小限制),另请参阅生产注意事项

从 MongoDB 4.2 开始,如果在操作完成之前,发出 db.collection.find() 的客户端断开连接,MongoDB 将使用killOpdb.collection.find() 标记为终止。

8.0版本新增

您可以使用查询设置来设置索引提示、设置操作拒绝过滤器以及其他字段。这些设置将应用于整个集群上的查询结构。在关闭之后,集群将保留这些设置。

在查询规划期间,查询优化器将使用查询设置作为附加输入,这样会影响为运行查询而选择的计划。您还可以使用查询设置来阻塞查询结构。

要添加查询设置并探索示例,请参阅 setQuerySettings

您可以为finddistinctaggregate命令添加查询设置。

查询设置具有更多功能,并且比已弃用的索引筛选器更受青睐。

要删除查询设置,请使用 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()
  • 以下操作将返回 BIOS 集合中的文档,其中,_id 等于 5

    db.bios.find( { _id: 5 } )
  • 以下操作返回 bios 集合中的文档,其中 name 嵌入式文档中的字段 last 等于 "Hopper"

    db.bios.find( { "name.last": "Hopper" } )

    注意

    要访问嵌入式文档中的字段,请使用点符号 ("<embedded document>.<field>")。

要查找符合一组选择条件的文档,请使用 <criteria> 参数调用 find()

MongoDB 提供各种查询运算符来指定标准。

  • 以下操作使用 $in 操作符返回 bios 集合中的文档,其中 _id 等于 5ObjectId("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正则表达式作为值的文档,请调用find()并将bsonRegExp选项设立为truebsonRegExp选项允许您返回无法表示为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: 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() 投影可以接受 聚合表达式和语法。

使用聚合表达式和事务语法,您可以投影新字段或使用新值投影现有字段。例如,以下操作使用聚合表达式来重写 nameawards 字段的值,并纳入新字段 reportDatereportByreportNumber

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 }

提示

另请参阅:

find() 方法将游标返回到结果。

mongosh 中,如果未使用 var 关键字将返回的游标分配给变量,则该游标将自动迭代,最多可访问与查询匹配的前 20 个文档。可以更新 displayBatchSize 变量来更改自动迭代文档的数量。

以下示例将批处理大小设置为 3。未来 db.collection.find() 操作每次游标遍历仅返回 3 份文档。

config.set( "displayBatchSize", 3 )

如需手动遍历结果,请将返回的游标分配给带有 var 关键字的变量,如以下部分所示。

以下示例使用变量 myCursor 迭代游标并打印匹配的文档:

var myCursor = db.bios.find( );
myCursor

以下示例使用游标方法 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() 遍历游标并访问文档:

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 } )

以下声明链接游标方法limit()sort()

db.bios.find().sort( { name: 1 } ).limit( 5 )
db.bios.find().limit( 5 ).sort( { name: 1 } )

这两个语句是等效的;也就是说,链接 limit()sort() 方法的顺序并不重要。 两个语句均返回前五个文档,由“名称”的升序排序决定。

您可以指定查询选项来修改查询行为并指示如何返回结果。

例如,要定义可在 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 集合:

1

运行:

db.createRole( { role: "Marketing", roles: [], privileges: [] } )
db.createRole( { role: "Sales", roles: [], privileges: [] } )
db.createRole( { role: "Development", roles: [], privileges: [] } )
db.createRole( { role: "Operations", roles: [], privileges: [] } )
2

创建名为 JohnJane 的用户,并赋予所需角色。将 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" }
]
} )
3

运行:

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 可以访问的文档:

1

运行:

db.auth( "John", "jn008" )
2

要使用系统变量,请将$$添加到变量名称的开头。将USER_ROLES系统变量指定为$$USER_ROLES

运行:

db.budget.find( {
$expr: {
$not: {
$eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ]
}
}
} )

上一示例从budget集合中返回至少与运行该示例的用户所具有的角色之一匹配的文档。为此,该示例使用$setIntersection返回文档,其中budget文档allowedRoles字段与$$USER_ROLES的用户角色集之间的交集不为空。

3

John 具有MarketingOperationsDevelopment 角色,且能看到以下文档:

[
{
_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 可以访问的文档:

1

运行:

db.auth( "Jane", "je009" )
2

运行:

db.budget.find( {
$expr: {
$not: {
$eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ]
}
}
} )
3

Jane 具有 SalesOperations 角色,且能看到以下文档:

[
{
_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
)

以下查询使用 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。此查询使用设置为 2limit 来仅返回两个文档,并使用设置为 trueshowRecordId 来返回文档在结果集中的位置:

db.users.find(
{},
{ username: 1, age: 1 },
{
limit: 2,
showRecordId: true
}
)

后退

db.collection.explain