对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

findAndModify(数据库命令)

findAndModify

更新并返回单个文档。默认情况下,返回的文档不包含更新所做的修改。要返回修改后的文档,请使用 new 选项。

提示

In mongosh, this command can also be run through the db.collection.findAndModify() helper method.

Helper methods are convenient for mongosh users, but they may not return the same level of information as database commands. In cases where the convenience is not needed or the additional return fields are required, use the database command.

此命令可用于以下环境中托管的部署:

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

注意

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

在版本5.0中进行了更改。

该命令具有以下语法:

db.runCommand(
{
findAndModify: <collection-name>,
query: <document>,
sort: <document>,
remove: <boolean>,
update: <document or aggregation pipeline>,
new: <boolean>,
fields: <document>,
upsert: <boolean>,
bypassDocumentValidation: <boolean>,
writeConcern: <document>,
maxTimeMS: <integer>,
collation: <document>,
arrayFilters: <array>,
hint: <document|string>,
comment: <any>,
let: <document> // Added in MongoDB 5.0
}
)

该命令接受以下字段:

字段
类型
说明

query

文档

可选。修改的选择条件。query 字段使用与 db.collection.find()方法中相同的查询选择器。尽管该查询可能匹配多个文档,但findAndModify 仅选择一个文档进行更新。

如果未指定,则默认为空文档。

如果查询参数不是文档,则操作出错。

sort

文档

Optional. Determines which document the operation updates if the query selects multiple documents. findAndModify updates the first document in the sort order specified by this argument.

如果 sort 参数不是文档,则操作错误。

MongoDB 不按特定顺序将文档存储在集合中。对包含重复值的字段进行排序时,可能会以任何顺序返回包含这些值的文档。

$sort 操作不是“稳定排序”,这意味着具有等效排序键的文档在输出中不一定能保持与输入相同的相对顺序。

如果排序条件中指定的字段在两个文档中都不存在,那么它们排序所依据的值是相同的。这两个文档可以以任何顺序返回。

如果需要一致的排序顺序,请在排序中至少纳入一个包含唯一值的字段。最简单方法是在排序查询中纳入 _id 字段。

有关更多信息,请参阅排序一致性

remove

布尔

必须指定 removeupdate 字段。删除 query 字段中指定的文档。将此字段设置为 true 可删除所选文档。默认值为 false

update

文档或数组

必须指定 removeupdate 字段。执行所选文档的更新。

new

布尔

可选。 当true时,返回更新后的文档而不是原始文档。 默认值为false

fields

文档

可选。要返回的字段的子集。fields 文档指定包含附带 1 的字段,如:fields: { <field1>: 1, <field2>: 1, ... }。请参阅投影

如果字段参数不是文档,则操作错误。

upsert

布尔

可选。与 update 字段结合使用。

true findAndModify时, 会:

  • 如果没有文档与 query 匹配,则创建一个新文档。有关详细信息,请参阅更新或插入行为

  • 更新与 query 匹配的单份文档。

为避免出现多个 upsert 操作,请确保 query 字段具有唯一索引。请参阅使用唯一索引进行 upsert 以查看示例。

默认值为 false;即,在未找到匹配项时插入新文档。

bypassDocumentValidation

布尔

Optional. Enables findAndModify to bypass schema validation during the operation. This lets you update documents that do not meet the validation requirements.

writeConcern

文档

可选。指定写关注。 省略以使用默认的写关注。

如果是在事务中运行,则请勿显式设置此操作的写关注。要将写关注与事务一起使用,请参阅事务和写关注。

maxTimeMS

non-negative integer

可选。

指定时间限制(以毫秒为单位)。如果您未指定 maxTimeMS 值,操作将不会超时。如果值为 0 ,则显式指定默认无限制行为。

MongoDB 使用与 db.killOp() 相同的机制终止超过分配的时间限制的操作。MongoDB 仅在指定的中断点之一中终止操作。

findAndModify

字符串

要针对其运行该命令的集合。

collation

文档

可选。

可选。指定用于操作的排序规则

排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。

排序规则选项的语法如下:

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

指定排序规则时,locale 字段为必填字段;所有其他排序规则字段均为可选字段。有关字段的说明,请参阅排序规则文档

如果未指定排序规则,但集合具有默认排序规则(请参阅 db.createCollection()),则操作将使用为集合指定的排序规则。

如果没有为收集或操作指定排序规则,MongoDB 将使用先前版本中使用的简单二进制比较来进行字符串比较。

您不能为一个操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者如果执行带排序的查找,则不能使用一种排序规则进行查找而另一种排序规则进行排序。

arrayFilters

阵列

选修的。大量过滤器文档,用于确定针对大量字段的更新操作要修改哪些大量元素。

在更新文档中,使用 $[<identifier>] 筛选后的位置运算符来定义标识符,然后在数组筛选文档中引用该标识符。如果更新文档中未包含某一标识符,则无法获得该标识符的数组筛选文档。

<identifier> 必须以小写字母开头,且只能包含字母数字字符。

您可以在更新文档中多次包含相同的标识符;但对于更新文档中的每个不同标识符 ($[identifier]),您必须准确指定一个对应的数组筛选器文档。也就是说,不能为同一个标识符指定多个数组筛选器文档。例如,如果更新语句包含标识符 x(可能多次),则不能为 arrayFilters 指定以下内容,其中包括 x 的 2 个单独的筛选器文档:

// INVALID
[
{ "x.a": { $gt: 85 } },
{ "x.b": { $gt: 80 } }
]

但是,您可以在单个过滤器文档中的同一标识符上指定复合条件,例如以下示例:

// Example 1
[
{ $or: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 2
[
{ $and: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 3
[
{ "x.a": { $gt: 85 }, "x.b": { $gt: 80 } }
]

For examples, see Array Update Operations with arrayFilters.

arrayFilters 不适用于使用聚合管道的更新。

hint

文档或字符串

可选。指定用于支持 query索引的文档或字符串。

该选项可以采用索引规范文档或索引名称字符串。

如果指定不存在的索引,则操作出错。

有关示例,请参阅为 hintfindAndModify操作指定 。

comment

any

可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:

注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。

文档

可选。

指定包含变量列表的文档。这样可以将变量与查询文本分开,从而提高命令的可读性。

文档语法为:

{
<variable_name_1>: <expression_1>,
...,
<variable_name_n>: <expression_n>
}

变量设置为表达式返回的值,并且之后不能再进行更改。

要访问命令中的变量值,请使用双美元符号前缀 ($$) 以及 $$<variable_name> 形式的变量名称。例如:$$targetTotal

要使用变量筛选结果,您必须在 $expr 操作符中访问该变量。

有关使用let 和变量的完整示例,请参阅在 let中使用变量。

版本 5.0 中的新增功能。

findAndModify命令返回包含以下字段的文档:

字段
类型
说明

value

文档

包含命令的返回值。有关详细信息,请参阅value

lastErrorObject

文档

包含有关更新文档的信息。有关详细信息,请参阅lastErrorObject

ok

数字

包含此命令的执行状态。成功时为 1,出错时则为 0

lastErrorObject 嵌入式文档包含以下字段:

字段
类型
说明

n

整型

包含与更新谓词匹配的文档数或命令插入或删除的文档数。

updatedExisting

布尔

如果为 update 操作,则包含 true

  • 更新了现有文档。

  • 已找到该文档,但它已处于所需的目标状态,因此实际并未进行任何更新。

upserted

文档

如果符合 upsert: trueupdate 操作生成了新文档,则包含已插入文档的 ObjectId

对于 remove 操作,如果此查询与某一文档匹配,value 则包含已删除的文档。如果此查询与要删除的文档不匹配,value 则包含 null

对于 update 操作,value 嵌入式文档包含以下内容:

  • 如果未设置 new 参数或为 false

    • 如果查询结果与文档匹配,则返回修改前的文档;

    • 否则,返回 null

  • 如果 newtrue

    • 如果查询返回匹配项,则返回更新后的文档;

    • 如果设置了 upsert: true 且没有与查询匹配的文档,则返回插入的文档;

    • 否则,返回 null

除非有唯一索引来防止重复,否则 upsert 可能会创建重复的文档。

以某一情况为例,其中不存在名为 Andy 的文档,且多个客户端大致会在同一时间发出以下命令:

db.runCommand(
{
findAndModify: "people",
query: { name: "Andy" },
update: { $inc: { score: 1 } },
upsert: true
}
)

If all findAndModify operations finish the query phase before any client successfully inserts data, and there is no unique index on the name field, each findAndModify operation may result in an insert, creating multiple documents with name: Andy.

A unique index on the name field ensures that only one document is created. With a unique index in place, the multiple findAndModify operations now exhibit the following behavior:

  • Exactly one findAndModify operation will successfully insert a new document.

  • Other findAndModify operations either update the newly-inserted document or fail due to a unique key collision.

    In order for other findAndModify operations to update the newly-inserted document, all of the following conditions must be met:

    • 目标collection具有会导致重复键错误的唯一索引。

    • 更新操作不是updateManymultifalse

    • 更新匹配条件为:

      • 单个相等谓词。例如 { "fieldA" : "valueA" }

      • 等式谓词的逻辑 AND。例如 { "fieldA" : "valueA", "fieldB" : "valueB" }

    • 相等谓词中的字段与唯一索引键模式中的字段匹配。

    • 更新操作不会修改唯一索引键模式中的任何字段。

下表显示了upsert操作的示例,当发生键冲突时,这些操作要么导致更新,要么失败。

唯一索引键模式
更新操作
结果
{ name : 1 }
db.people.updateOne(
{ name: "Andy" },
{ $inc: { score: 1 } },
{ upsert: true }
)

匹配文档的score字段递增 1。

{ name : 1 }
db.people.updateOne(
{ name: { $ne: "Joe" } },
{ $set: { name: "Andy" } },
{ upsert: true }
)

操作失败是因为它修改了唯一索引键模式 ( name ) 中的字段。

{ name : 1 }
db.people.updateOne(
{ name: "Andy", email: "andy@xyz.com" },
{ $set: { active: false } },
{ upsert: true }
)

操作失败,因为等值谓词字段( nameemail )与索引键字段( name )不匹配。

To use findAndModify on a sharded collection:

  • 如果仅针对一个分片,则可以在 query 字段中使用部分分片键,或者,

  • 可以在 query字段中提供完整分片键的相等条件。

  • 从版本 7.1 开始,您不需要在查询规范中提供分片键_id 字段。

分片集合中的文档可能缺少分片键字段。要定位缺失分片键的文档,可将 null 等值匹配与其他过滤条件(例如针对 _id 字段)结合使用。例如:

{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key

您可以更新文档的分片键值,除非分片键字段是不可变的 _id 字段。

警告

分片集合中的文档可能缺少分片键字段。采取预防措施,避免在更改文档的分片键值时意外删除分片键。

要使用 findAndModify更新现有分片键值:

  • 必须mongos 上运行。请勿直接在分片上运行操作。

  • 必须事务中运行,或者以可重试写入的形式运行。

  • 必须在完整分片键上包含相等筛选器。

分片的集合中的文档可能缺少分片键字段。要使用findAndModify 设立文档缺失的分片键:

  • 必须mongos 上运行。请勿直接在分片上运行操作。

  • 如果新的分片键值不是 null,则必须事务中运行或作为可重试写入运行。

  • 必须在完整分片键上包含相等筛选器。

提示

由于缺失的键值是作为 null 相等匹配的一部分返回的,因此为避免更新空值键,请酌情纳入其他查询条件(例如 _id 字段)。

另请参阅:

The findAndModify command adds support for the bypassDocumentValidation option, which lets you bypass schema validation when inserting or updating documents in a collection with validation rules.

更新文档时,findAndModifyupdateOne() 方法的运行方式不同:

  • 如果多个文档符合更新条件,则对于findAndModify ,您可以指定sort 以对更新哪个文档提供某种控制措施。

    updateOne() 更新第一个匹配的文档。

  • 默认下,findAndModify 返回一个对象,其中包含文档修改前的版本以及操作的状态。要获取更新后的文档,请使用new 选项。

    updateOne() 方法返回一个包含操作状态的 WriteResult() 对象。

    要返回更新后的文档,请使用 find() 方法。但是,在更新和文档检索之间,其他更新可能已修改了文档。此外,如果更新只修改了一个文档,但有多个文档匹配,则需要使用额外的逻辑来识别已更新的文档。

修改单个文档时, 和findAndModify updateOne()方法都会自动更新文档。有关这些方法的交互和操作顺序的更多详细信息,请参阅原子性和事务。

findAndModify can be used inside distributed transactions.

重要

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

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

如果分布式事务不是跨分片写入事务,则可以在该事务中创建集合和索引。

findAndModify with upsert: true can be run on an existing collection or a non-existing collection. If run on a non-existing collection, the operation creates the collection.

如果是在事务中运行,则请勿显式设置此操作的写关注。要将写关注与事务一起使用,请参阅事务和写关注。

如果 findAndModify 操作由于未实现写关注(write concern)失败,则该操作将返回 writeConcernError 文档。

以下命令会更新 people 集合中符合 query 条件的现有文档:

db.runCommand(
{
findAndModify: "people",
query: { name: "Tom", state: "active", rating: { $gt: 10 } },
sort: { rating: 1 },
update: { $inc: { score: 1 } }
}
)

此命令会执行以下操作:

  1. querypeople 集合中找到一个文档,其中 name 字段的值为 Tomstate 字段的值为 activerating 字段的值为 greater than 10。

  2. sort 会对查询结果进行升序排序。如果多个文档匹配 query 条件,则该命令会修改排序中的第一个文档。

  3. update 会将 score 字段的值increments 1。

  4. 此命令将返回一个包含以下字段的文档:

    • 包含此命令详细信息的 lastErrorObject 字段,其中包括为 trueupdatedExisting 字段,以及

    • 包含为此更新选择的原始未修改文档的 value 字段:

      {
      "lastErrorObject" : {
      "connectionId" : 1,
      "updatedExisting" : true,
      "n" : 1,
      "syncMillis" : 0,
      "writtenTo" : null,
      "err" : null,
      "ok" : 1
      },
      value" : {
      "_id" : ObjectId("54f62d2885e4be1f982b9c9c"),
      "name" : "Tom",
      "state" : "active",
      "rating" : 100,
      "score" : 5
      },
      "ok" : 1
      }

要在value字段中返回更新后的文档,请在命令中添加new:true选项。

如果没有文档与 query 条件匹配,此命令则会返回一个在 value 字段中包含 null 的文档:

{ "value" : null, "ok" : 1 }

mongosh,许多驱动程序都提供 辅助方法。使用Shell findAndModify()助手,前一操作可以采用以下形式:

db.people.findAndModify( {
query: { name: "Tom", state: "active", rating: { $gt: 10 } },
sort: { rating: 1 },
update: { $inc: { score: 1 } }
} );

但是, findAndModify() Shell 助手方法仅返回未修改的文档,或者,如果newtrue ,则返回更新的文档。

{
"_id" : ObjectId("54f62d2885e4be1f982b9c9c"),
"name" : "Tom",
"state" : "active",
"rating" : 100,
"score" : 5
}

以下命令使用 upsert: true 更新匹配文档,如果不存在匹配,则插入新文档:

db.runCommand(
{
findAndModify: "people",
query: { name: "Gus", state: "active", rating: 100 },
sort: { rating: 1 },
update: { $inc: { score: 1 } },
upsert: true
}
)

如果此命令找到匹配的文档,则会执行更新。

如果此命令找到匹配的文档,则符合 upsert: trueupdate 操作则会触发插入并返回包含以下字段的文档:

  • 包含此命令详细信息的 lastErrorObject 字段,其中包括包含新插入文档的 _id 值的字段 upserted,以及

  • 包含 nullvalue 字段。

{
"value" : null,
"lastErrorObject" : {
"updatedExisting" : false,
"n" : 1,
"upserted" : ObjectId("54f62c8bc85d4472eadea26f")
},
"ok" : 1
}

以下命令使用 upsert: truenew: true 来更新匹配文档或插入新文档,并在 value 字段中返回新文档或更新文档。

在以下示例中,people 集合中没有文档与 query 条件匹配:

db.runCommand(
{
findAndModify: "people",
query: { name: "Pascal", state: "active", rating: 25 },
sort: { rating: 1 },
update: { $inc: { score: 1 } },
upsert: true,
new: true
}
)

此命令将在 value 字段中返回新插入的文档:

{
"lastErrorObject" : {
"connectionId" : 1,
"updatedExisting" : false,
"upserted" : ObjectId("54f62bbfc85d4472eadea26d"),
"n" : 1,
"syncMillis" : 0,
"writtenTo" : null,
"err" : null,
"ok" : 1
},
"value" : {
"_id" : ObjectId("54f62bbfc85d4472eadea26d"),
"name" : "Pascal",
"rating" : 25,
"state" : "active",
"score" : 1
},
"ok" : 1
}

通过在 rating 字段中包含 sort 规范,以下示例从 people 集合中删除 state 值为 active 且具有匹配文档中最低rating 的单个文档:

db.runCommand(
{
findAndModify: "people",
query: { state: "active" },
sort: { rating: 1 },
remove: true
}
)

此命令将返回已删除的文档:

{
"lastErrorObject" : {
"connectionId" : 1,
"n" : 1,
"syncMillis" : 0,
"writtenTo" : null,
"err" : null,
"ok" : 1
},
"value" : {
"_id" : ObjectId("54f62a6785e4be1f982b9c9b"),
"name" : "XYZ123",
"score" : 1,
"state" : "active",
"rating" : 3
},
"ok" : 1
}

排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。

集合 myColl 包含以下文档:

{ _id: 1, category: "café", status: "A" }
{ _id: 2, category: "cafe", status: "a" }
{ _id: 3, category: "cafE", status: "a" }

以下操作包括排序规则选项:

db.runCommand(
{
findAndModify: "myColl",
query: { category: "cafe", status: "a" },
sort: { category: 1 },
update: { $set: { status: "Updated" } },
collation: { locale: "fr", strength: 1 }
}
)

该操作将返回以下文档:

{
"lastErrorObject" : {
"updatedExisting" : true,
"n" : 1
},
"value" : {
"_id" : 1,
"category" : "café",
"status" : "A"
},
"ok" : 1
}

注意

arrayFilters 不适用于使用聚合管道的更新。

更新数组字段时,您可以指定 arrayFilters 确定要更新哪些数组元素。

注意

arrayFilters 不适用于使用聚合管道的更新。

使用以下文档创建集合 students

db.students.insertMany( [
{ "_id" : 1, "grades" : [ 95, 92, 90 ] },
{ "_id" : 2, "grades" : [ 98, 100, 102 ] },
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }
] )

要更新grades数组中所有大于或等于100的元素,请使用带有arrayFilters选项的位置$[<identifier>]操作符:

db.runCommand(
{
findAndModify: "students",
query: { grades: { $gte: 100 } },
update: { $set: { "grades.$[element]" : 100 } },
arrayFilters: [ { "element": { $gte: 100 } } ]
}
)

该操作更新单个文档的 grades 字段,完成该操作后,集合中将包含以下文档:

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 100 ] }
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }

注意

arrayFilters 不适用于使用聚合管道的更新。

使用以下文档创建集合 students2

db.students2.insertMany( [
{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 90, "std" : 4 },
{ "grade" : 85, "mean" : 85, "std" : 6 }
]
},
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}
] )

以下操作查找_id字段等于1的文档,并使用筛选后的位置运算符$[<identifier>]arrayFilters来更新grades数组中分数大于以下值的所有元素的mean :小于或等于85

db.runCommand(
{
findAndModify: "students2",
query: { _id : 1 },
update: { $set: { "grades.$[elem].mean" : 100 } },
arrayFilters: [ { "elem.grade": { $gte: 85 } } ]
}
)

该操作更新单个文档的 grades 字段,完成该操作后,集合中将包含以下文档:

{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 100, "std" : 4 },
{ "grade" : 85, "mean" : 100, "std" : 6 }
]
}
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}

findAndModify 可以接受聚合管道以用于更新。该管道可以由以下阶段组成:

使用聚合管道可以进行更具表现力的更新声明,例如基于当前字段值的表达条件更新或使用另一个字段的值更新一个字段。

例如,使用以下文档创建名为 students2 的集合:

db.students2.insertMany( [
{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 90, "std" : 4 },
{ "grade" : 85, "mean" : 85, "std" : 6 }
]
},
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}
] )

以下操作查找 _id 字段等于 1 的文档,并使用聚合管道根据 grades 字段计算新字段 total 的值:

db.runCommand(
{
findAndModify: "students2",
query: { "_id" : 1 },
update: [ { $set: { "total" : { $sum: "$grades.grade" } } } ],
new: true
}
)

注意

管道中使用的 $set 指的是聚合阶段 $set 而不是更新操作符 $set

操作完成后,集合有以下文档:

{
"_id" : 1,
"grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" :85, "std" : 6 } ],
"total" : 250
}
{
"_id" : 2,
"grades" : [ { "grade" : 90, "mean" : 75, "std" : 6 }, { "grade" : 87, "mean" : 90, "std" : 3 }, { "grade" : 85, "mean" : 85,"std" : 4 } ]
}

mongosh members中,使用以下文档创建 集合:

db.members.insertMany( [
{ "_id" : 1, "member" : "abc123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null },
{ "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" },
{ "_id" : 3, "member" : "lmn123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null },
{ "_id" : 4, "member" : "pqr123", "status" : "D", "points" : 20, "misc1" : "Deactivated", "misc2" : null },
{ "_id" : 5, "member" : "ijk123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null },
{ "_id" : 6, "member" : "cde123", "status" : "A", "points" : 86, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
] )

在集合上创建以下索引:

db.members.createIndex( { status: 1 } )
db.members.createIndex( { points: 1 } )

以下操作会显式提示使用索引 { status: 1 }

db.runCommand({
findAndModify: "members",
query: { "points": { $lte: 20 }, "status": "P" },
remove: true,
hint: { status: 1 }
})

注意

如果指定不存在的索引,则操作出错。

要查看使用的索引,请对操作运行 explain

db.runCommand(
{
explain: {
findAndModify: "members",
query: { "points": { $lte: 20 }, "status": "P" },
remove: true,
hint: { status: 1 }
},
verbosity: "queryPlanner"
}
)

版本 5.0 中的新增功能。

要定义可在命令中其他位置访问的变量,请使用 let 选项。

注意

要使用变量筛选结果,您必须在 $expr 操作符中访问该变量。

创建集合 cakeFlavors

db.cakeFlavors.insertMany( [
{ _id: 1, flavor: "chocolate" },
{ _id: 2, flavor: "strawberry" },
{ _id: 3, flavor: "cherry" }
] )

以下示例在 let 中定义了 targetFlavor 变量,并使用这些变量将蛋糕口味从樱桃更改为橙子:

db.cakeFlavors.runCommand( {
findAndModify: db.cakeFlavors.getName(),
query: { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } },
update: { flavor: "orange" },
let: { targetFlavor: "cherry" }
} )