文档菜单
文档首页
/
MongoDB 手册
/ / /

db.collection.find()

本页

  • 定义
  • 兼容性
  • 语法
  • 行为
  • 示例
  • 了解更多

MongoDB与驱动程序

本页记录了一个mongosh 方法。要查看MongoDB驱动程序中的等效方法,请参阅您所使用的编程语言的相应页面

C#Java SyncNode.jsPyMongoCC++GoJava RSKotlin CoroutineKotlin SyncPHPMongoidRustScala
db.collection.find(查询, 投影, 选项)

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

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

此方法在以下环境中托管部署中可用

  • MongoDB Atlas:MongoDB在云中的托管服务

注意

此命令在所有MongoDB Atlas集群中受支持。有关Atlas对所有命令的支持信息,请参阅不受支持的命令。

find() 方法有以下形式

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

方法 find() 接受以下参数

参数
类型
描述
文档

可选。使用 查询操作符 指定选择过滤器。要返回集合中的所有文档,可以省略此参数或传递一个空文档 ({})。

文档

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

文档

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

重要

语言一致性

为了使 find()findAndModify() 投影与聚合的 $project 阶段保持一致,

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

{ <field1>: <value>, <field2>: <value> ... }
投影
描述
<field>: <1 或 true>
指定包含字段。如果您为投影值指定非零整数,则操作将值视为 true
<field>: <0 或 false>
指定排除字段。
"<field>.$": <1 或 true>

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

不适用于 视图。

<field>: <数组投影>

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

不适用于 视图。

<field>: <$meta 表达式>

使用 $meta 运算符表达式来指定包含可用的 每文档元数据

不适用于 视图。

<field>: <聚合表达式>

指定投影字段的值。

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

  • 如果您为投影值指定非数字、非布尔字面量(例如字面量字符串、数组或运算符表达式),则字段以新值投影,例如

    • { 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游标。需要tailable设置为true
collation
更新操作的排序设置。
comment
向查询添加一个$comment,在性能分析器日志中显示。
explain
根据提供的详细模式添加解释输出。
hint
强制查询优化器在查询中使用特定的索引。
limit
设置结果集中返回的文档数限制。
max
特定索引的排他性上限。
maxAwaitTimeMS
服务器等待新文档以满足tailable游标查询的最大时间量。需要tailableawaitData设置为true
maxTimeMS
服务器允许查询运行的最大时间(以毫秒为单位)。
min
特定索引的包含性下限。
noCursorTimeout
服务器是否应在一段时间的不活动后超时游标(默认10分钟)。
readConcern
指定查询的读取关注级别。
readPreference
指定查询的读取偏好级别。
returnKey
是否只返回查询的索引键。
showRecordId
如果将$recordId字段添加到返回的文档中。该$recordId表示文档在结果集中的位置。
skip
在返回结果集中的第一个文档之前要跳过的文档数。
sort
结果集中返回的文档的顺序。排序中指定的字段必须有索引。
tailable
指示游标是否为tailable。Tailable游标在查询的初始结果耗尽后仍然保持打开状态。Tailable游标仅在有界集合上可用。

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

  • 点表示法,例如 "field.nestedfield": <value>

  • 嵌套形式,例如 { field: { nestedfield: <value> } }

默认情况下,_id 字段包含在返回的文档中,除非你在投影中明确指定 _id: 0 来抑制该字段。

投影中不能同时包含包含和排除指定,除非是 _id 字段。

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

  • 在显式排除字段的投影中,_id 是唯一可以显式包含的字段;然而,_id 字段默认包含。

请参阅投影示例。

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

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

提示

另请参阅

要指定 读取关注,请使用 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

注意

要强制在集合中执行数据类型,请使用 Schema Validation。

对于在会话中创建的游标,您不能在会话外调用 getMore

类似地,对于在会话外创建的游标,您不能在会话内调用 getMore

MongoDB 驱动程序和 mongosh 将所有操作与服务器会话关联,除了未确认的写操作。对于未明确与会话关联的操作(即使用 Mongo.startSession()),MongoDB 驱动程序和 mongosh 创建一个隐式会话并将其与操作关联。

如果会话空闲超过30分钟,MongoDB服务器将该会话标记为过期,并可能随时关闭它。当MongoDB服务器关闭会话时,它也会终止会话中所有正在进行的操作和打开的光标。这包括配置了noCursorTimeout()maxTimeMS()大于30分钟的光标。

对于可能空闲超过30分钟的操作,可以使用Mongo.startSession()将操作与显式会话关联,并定期使用refreshSessions命令刷新会话。有关更多信息,请参阅会话空闲超时

db.collection.find()可以在分布式事务中使用。

  • 对于在事务外创建的光标,您不能在事务中调用getMore

  • 对于在事务中创建的光标,您不能在事务外调用getMore

重要

在大多数情况下,分布式事务相比单文档写入会产生更高的性能成本,分布式事务的可用性不应替代有效的模式设计。对于许多场景,去规范化数据模型(嵌入文档和数组)将继续是您数据和用例的最佳选择。也就是说,对于许多场景,适当的数据建模将最小化分布式事务的需求。

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

从MongoDB 4.2版本开始,如果执行db.collection.find()的客户端在操作完成前断开连接,MongoDB将使用killOp命令将db.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" } )

    注意

    要访问嵌套文档中的字段,请使用 点表示法 (<嵌套文档>.<字段>)。

要查找符合一组选择标准的文档,请使用带有 <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/ } }
    )

有关查询运算符的列表,请参阅 查询选择器。

使用比较运算符组合来指定字段的范围。以下操作从文档中返回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') } } )

有关查询运算符的列表,请参阅 查询选择器。

以下操作返回所有来自的文档,其中birth字段大于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 字段包含字段 first,其值为 "Yukihiro",以及字段 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 数组。

  • 以下操作返回包含元素 "UNIX"contribs 数组的 bios 集合 中的文档。

    db.bios.find( { contribs: "UNIX" } )
  • 以下操作返回包含元素 "ALGOL""Lisp"contribs 数组的 bios 集合 中的文档。

    db.bios.find( { contribs: { $in: [ "ALGOL", "Lisp" ]} } )
  • 以下操作使用 $all 查询操作符返回包含元素 "ALGOL""Lisp"contribs 数组的 bios 集合 中的文档。

    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正则表达式作为值的文档,请使用设置 bsonRegExp 选项为 truefind() 方法。bsonRegExp 选项允许您返回无法表示为JavaScript正则表达式的正则表达式。

以下操作返回名为 testbson 的集合中,字段名为 foo 的值是 BSONRegExp 类型的文档。

db.testbson.find( {}, {}, { bsonRegExp: true } )
[
{
_id: ObjectId('65e8ba8a4b3c33a76e6cacca'),
foo: BSONRegExp('(?-i)AA_', 'i')
}
]

投影 参数指定要返回哪些字段。该参数包含包含或排除指定项,但不能同时包含两者,除非排除项是 _id 字段。

注意

除非在投影文档中明确排除 _id 字段 _id: 0,否则将返回 _id 字段。

以下操作在 bios 集合 中查找所有文档,并仅返回 name 字段、contribs 字段和 _id 字段。

db.bios.find( { }, { name: 1, contribs: 1 } )

注意

除非在投影文档中明确排除 _id 字段 _id: 0,否则将返回 _id 字段。

以下操作查询 bios 集合,并返回所有字段,除了嵌入文档中的 name 字段的第一个字段和 birth 字段

db.bios.find(
{ contribs: 'OOP' },
{ 'name.first': 0, birth: 0 }
)

注意

除非在投影文档中明确排除 _id 字段 _id: 0,否则将返回 _id 字段。

以下操作在 bios 集合 中查找文档,并仅返回 name 字段和 contribs 字段

db.bios.find(
{ },
{ name: 1, contribs: 1, _id: 0 }
)

以下操作查询 bios 集合,并返回嵌入文档中的 name 字段的最后一个字段和 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);

mongoshdrivers 提供了多个光标方法,这些方法调用 find() 方法返回的光标以修改其行为。

sort() 方法对结果集中的文档进行排序。以下操作返回按 name 字段升序排序的 bios 集合 中的文档

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

sort() 方法对应于 SQL 中的 ORDER BY 语句。

方法 limit() 用于限制结果集中文档的数量。以下操作在 bios 集合 中最多返回 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() 方法的顺序不重要。两个语句都返回按 'name' 字段升序排序的前五个文档。

您可以通过指定查询选项来修改查询行为并指示结果返回方式。

例如,为了在 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 仍然包含用户的角色。

以下示例展示了如何使用options字段在find()查询中。使用以下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。此查询将 limit 设置为 2 以返回仅两个文档,并将 showRecordId 设置为 true 以返回文档在结果集中的位置

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

返回上一页

db.collection.explain

© . This site is unofficial and not affiliated with MongoDB, Inc.