Bulk.find.upsert()

On this page本页内容

Tip提示

Starting in version 3.2, MongoDB also provides the db.collection.bulkWrite() method for performing bulk write operations.从3.2版开始,MongoDB还提供了db.collection.bulkWrite()方法来执行批量写入操作。

Description描述

Bulk.find.upsert()

Sets the upsert option to true for an update or a replacement operation and has the following syntax:对于更新或替换操作,将upsert选项设置为true,并具有以下语法:

Bulk.find(<query>).upsert().update(<update>);
Bulk.find(<query>).upsert().updateOne(<update>);
Bulk.find(<query>).upsert().replaceOne(<replacement>);

With the upsert option set to true, if no matching documents exist for the Bulk.find() condition, then the update or the replacement operation performs an insert. upsert选项设置为true时,如果Bulk.find()条件不存在匹配的文档,则更新或替换操作将执行插入。If a matching document does exist, then the update or replacement operation performs the specified update or replacement.如果匹配的文档确实存在,则更新或替换操作将执行指定的更新或替换。

Use Bulk.find.upsert() with the following write operations:Bulk.find.upsert()用于以下写入操作:

Behavior行为

The following describe the insert behavior of various write operations when used in conjunction with Bulk.find.upsert().下面描述了与Bulk.find.upsert()结合使用时各种写入操作的插入行为。

Insert for Bulk.find.replaceOne()的插入

The Bulk.find.replaceOne() method accepts, as its parameter, a replacement document that only contains field and value pairs:Bulk.find.replaceOne()方法接受仅包含字段和值对的替换文档作为其参数:

var bulk = db.items.initializeUnorderedBulkOp();
bulk.find( { item: "abc123" } ).upsert().replaceOne(
   {
     item: "abc123",
     status: "P",
     points: 100,
   }
);
bulk.execute();

If the replacement operation with the Bulk.find.upsert() option performs an insert, the inserted document is the replacement document. 如果使用Bulk.find.upsert()选项的替换操作执行插入,则插入的文档就是替换文档。If neither the replacement document nor the query document specifies an _id field, MongoDB adds the _id field:如果替换文档和查询文档都没有指定_id字段,MongoDB将添加_id字段:

{
  "_id" : ObjectId("52ded3b398ca567f5c97ac9e"),
  "item" : "abc123",
  "status" : "P",
  "points" : 100
}

Insert for Bulk.find.updateOne()的插入

The Bulk.find.updateOne() method accepts as its parameter either:Bulk.find.updateOne()方法接受以下任一项作为其参数

  • a replacement document that contains only field and value pairs (same as Bulk.find.replaceOne()),仅包含字段和值对的替换文档(与Bulk.find.replaceOne()相同),
  • an update document that contains only update operator expressions, or仅包含更新运算符表达式的更新文档,或
  • an aggregation pipeline (Starting in MongoDB 4.2).聚合管道(从MongoDB 4.2开始)。

Field and Value Pairs字段和值对

If the parameter is a replacement document that contains only field and value pairs:如果参数是仅包含字段和值对的替换文档:

var bulk = db.items.initializeUnorderedBulkOp();
bulk.find( { status: "P" } ).upsert().updateOne(
   {
     item: "TBD",
     points: 0,
     inStock: true,
     status: "I"
   }
);
bulk.execute();

Then, if the update operation with the Bulk.find.upsert() option performs an insert, the inserted document is the replacement document. 然后,如果使用Bulk.find.upsert()选项的更新操作执行插入,则插入的文档就是替换文档。If neither the replacement document nor the query document specifies an _id field, MongoDB adds the _id field:如果替换文档和查询文档都没有指定_id字段,MongoDB将添加_id字段:

{
  "_id" : ObjectId("52ded5a898ca567f5c97ac9f"),
  "item" : "TBD",
  "points" : 0,
  "inStock" : true,
  "status" : "I"
}

Update Operator Expressions更新运算符表达式

If the parameter is an update document that contains only update operator expressions:如果参数是仅包含更新运算符表达式的更新文档:

var bulk = db.items.initializeUnorderedBulkOp();
bulk.find( { status: "P", item: null } ).upsert().updateOne(
   {
     $setOnInsert: { qty: 0, inStock: true },
     $set: { points: 0 }
   }
);
bulk.execute();

Then, if the update operation with the Bulk.find.upsert() option performs an insert, the update operation inserts a document with field and values from the query document of the Bulk.find() method and then applies the specified updates from the update document. 然后,如果使用Bulk.find.upsert()选项的更新操作执行插入操作,则更新操作将从Bulk.find()方法的查询文档中插入一个包含字段和值的文档,然后应用更新文档中的指定更新。If neither the update document nor the query document specifies an _id field, MongoDB adds the _id field:如果更新文档和查询文档都没有指定_id字段,MongoDB将添加_id字段:

{
   "_id" : ObjectId("5e28d1a1500153bc2872dadd"),
   "item" : null,
   "status" : "P",
   "inStock" : true,
   "points" : 0,
   "qty" : 0
}

Aggregation Pipeline聚合管道

Starting in version 4.2, update methods can accept an aggregation pipeline. 从4.2版开始更新方法可以接受聚合管道。For example, the following uses:例如,以下使用:

  • the $replaceRoot stage which can provide somewhat similar behavior to a $setOnInsert update operator expression,$replaceRoot阶段可以提供与$setOnInsert更新运算符表达式类似的行为,
  • the $set stage which can provide similar behavior to the $set update operator expression,$set阶段可以提供与$set更新运算符表达式类似的行为,
  • the aggregation variable NOW, which resolves to the current datetime and can provide similar behavior to a $currentDate update operator expression.聚合变量NOW,它解析为当前日期时间,可以提供与$currentDate更新运算符表达式类似的行为。
var bulk = db.items.initializeUnorderedBulkOp();
bulk.find( { item: "Not Found", status: "P" } ).upsert().updateOne(
   [
      { $replaceRoot: { newRoot: { $mergeObjects: [ { qty: 0, inStock: true }, "$$ROOT"  ] } } },
      { $set: { points: 0, lastModified: "$$NOW" } }
   ]
);
bulk.execute();

Then, if the update operation with the Bulk.find.upsert() option performs an insert, the update operation inserts a document with field and values from the query document of the Bulk.find() method and then applies the specified aggregation pipeline. 然后,如果使用Bulk.find.upsert()选项的更新操作执行了插入操作,则更新操作将从Bulk.find()方法的查询文档中插入一个包含字段和值的文档,然后应用指定的聚合管道。If neither the update document nor the query document specifies an _id field, MongoDB adds the _id field:如果更新文档和查询文档都没有指定_id字段,MongoDB将添加_id字段:

{
   "_id" : ObjectId("5e28cf1e500153bc2872d49f"),
   "qty" : 0,
   "inStock" : true,
   "item" : "Not Found",
   "status" : "P",
   "points" : 0,
   "lastModified" : ISODate("2020-01-22T22:39:26.789Z")
}

Insert for Bulk.find.update()的插入

When using upsert() with the multiple document update method Bulk.find.update(), if no documents match the query condition, the update operation inserts a single document.当将upsert()与多文档更新方法Bulk.find.update()一起使用时,如果没有文档符合查询条件,则更新操作将插入单个文档。

The Bulk.find.update() method accepts as its parameter either:Bulk.find.update()方法接受以下任一项作为其参数:

  • an update document that contains only update operator expressions, or仅包含更新运算符表达式的更新文档,或
  • an aggregation pipeline (Starting in MongoDB 4.2).聚合管道(从MongoDB 4.2开始)。

Update Operator Expressions更新运算符表达式

If the parameter is an update document that contains only update operator expressions:如果参数是仅包含更新运算符表达式的更新文档:

var bulk = db.items.initializeUnorderedBulkOp();
bulk.find( { status: "P" } ).upsert().update(
   {
     $setOnInsert: { qty: 0, inStock: true },
     $set: { status: "I", points: "0" }
   }
);
bulk.execute();

Then, if the update operation with the Bulk.find.upsert() option performs an insert, the update operation inserts a single document with the fields and values from the query document of the Bulk.find() method and then applies the specified update from the update document. 然后,如果使用Bulk.find.upsert()选项的更新操作执行了插入操作,则更新操作将插入一个包含Bulk.find()方法的查询文档中的字段和值的文档,然后从更新文档中应用指定的更新。If neither the update document nor the query document specifies an _id field, MongoDB adds the _id field:如果更新文档和查询文档都没有指定_id字段,MongoDB将添加_id字段:

{
   "_id": ObjectId("52ded81a98ca567f5c97aca1"),
   "status": "I",
   "qty": 0,
   "inStock": true,
   "points": "0"
}

Aggregation Pipeline聚合管道

Starting in version 4.2, update methods can accept an aggregation pipeline. 从4.2版开始更新方法可以接受聚合管道。For example, the following uses:例如,以下使用:

  • the $replaceRoot stage which can provide somewhat similar behavior to a $setOnInsert update operator expression,$replaceRoot阶段可以提供与$setOnInsert更新运算符表达式类似的行为,
  • the $set stage which can provide similar behavior to the $set update operator expression,$set阶段可以提供与$set更新运算符表达式类似的行为,
  • the aggregation variable NOW, which resolves to the current datetime and can provide similar behavior to the $currentDate update operator expression. 聚合变量NOW,它解析为当前日期时间,可以提供与$currentDate更新运算符表达式类似的行为。The value of NOW remains the same throughout the pipeline. NOW的价值在整个管道中保持不变。To access aggregation variables, prefix the variable with double dollar signs $$ and enclose in quotes.要访问聚合变量,请在变量前面加上双美元符号$$并用引号括起来。
var bulk = db.items.initializeUnorderedBulkOp();
bulk.find( { item: "New Item", status: "P" } ).upsert().update(
   [
      { $replaceRoot: { newRoot: { $mergeObjects: [ { qty: 0, inStock: true }, "$$ROOT"  ] } } },
      { $set: { points: 0, lastModified: "$$NOW" } }
   ]
);
bulk.execute();

Then, if the update operation with the Bulk.find.upsert() option performs an insert, the update operation inserts a single document with the fields and values from the query document of the Bulk.find() method and then applies the aggregation pipeline. 然后,如果使用Bulk.find.upsert()选项的更新操作执行插入操作,则更新操作将插入一个包含Bulk.find()方法的查询文档中的字段和值的文档,然后应用聚合管道。If neither the update document nor the query document specifies an _id field, MongoDB adds the _id field:如果更新文档和查询文档都没有指定_id字段,MongoDB将添加_id字段:

{
   "_id" : ObjectId("5e2920a5b4c550aad59d18a1"),
   "qty" : 0,
   "inStock" : true,
   "item" : "New Item",
   "status" : "P",
   "points" : 0,
   "lastModified" : ISODate("2020-01-23T04:27:17.780Z")
}
←  Bulk.find.update()Bulk.getOperations() →