Bulk.find.upsert()
提示
MongoDB 还提供了用于执行批量写入操作的 db.collection.bulkWrite()
方法。
说明
Bulk.find.upsert()
将更新或替换操作的 upsert 选项设置为 true,事务语法如下:
Bulk.find(<query>).upsert().update(<update>); Bulk.find(<query>).upsert().updateOne(<update>); Bulk.find(<query>).upsert().replaceOne(<replacement>); 将
upsert
选项设置为true
时,如果不存在Bulk.find()
条件的匹配文档,则更新或替换操作将执行插入。如果匹配的文档确实存在,那么更新或替换操作就会执行指定的更新或替换。使用
Bulk.find.upsert()
进行以下写入操作:
行为
下面描述了与 Bulk.find.upsert()
结合使用时各种写入操作的插入行为。
Insert for Bulk.find.replaceOne()
Bulk.find.replaceOne()
方法接受仅包含字段和值对的替换文档作为其参数:
var bulk = db.items.initializeUnorderedBulkOp(); bulk.find( { item: "abc123" } ).upsert().replaceOne( { item: "abc123", status: "P", points: 100, } ); bulk.execute();
如果带有 Bulk.find.upsert()
选项的替换操作执行插入,则插入的文档就是替换文档。如果替换文档和查询文档均未指定 _id
字段,则 MongoDB 将添加 _id
字段:
{ "_id" : ObjectId("52ded3b398ca567f5c97ac9e"), "item" : "abc123", "status" : "P", "points" : 100 }
Insert for Bulk.find.updateOne()
Bulk.find.updateOne()
方法接受以下任一项作为其参数:
仅包含字段和值对的替换文档(与
Bulk.find.replaceOne()
相同)、仅包含更新操作符表达式的更新文档,或
聚合管道。
字段和值对
如果 参数 是仅包含字段和值对的替换文档:
var bulk = db.items.initializeUnorderedBulkOp(); bulk.find( { status: "P" } ).upsert().updateOne( { item: "TBD", points: 0, inStock: true, status: "I" } ); bulk.execute();
然后,如果带 Bulk.find.upsert()
选项的更新操作执行插入,则插入的文档就是替换文档。如果替换文档和查询文档均未指定 _id
字段,则 MongoDB 将添加 _id
字段:
{ "_id" : ObjectId("52ded5a898ca567f5c97ac9f"), "item" : "TBD", "points" : 0, "inStock" : true, "status" : "I" }
更新操作符表达式
var bulk = db.items.initializeUnorderedBulkOp(); bulk.find( { status: "P", item: null } ).upsert().updateOne( { $setOnInsert: { qty: 0, inStock: true }, $set: { points: 0 } } ); bulk.execute();
接着,如果带 Bulk.find.upsert()
选项的更新操作执行插入,则该更新操作会插入一个文档(其字段和值来自 Bulk.find()
方法的查询文档),然后应用更新文档中的指定更新。如果更新文档和查询文档均未指定 _id
字段,则 MongoDB 将添加 _id
字段:
{ "_id" : ObjectId("5e28d1a1500153bc2872dadd"), "item" : null, "status" : "P", "inStock" : true, "points" : 0, "qty" : 0 }
聚合管道 (Aggregation Pipeline)
更新方法可以接受聚合管道。例如,以下使用:
$replaceRoot
阶段,它提供与$setOnInsert
更新操作符表达式略微相似的行为,聚合变量
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();
接着,如果带 Bulk.find.upsert()
选项的更新操作执行插入,则该更新操作会插入一个文档(其字段和值来自 Bulk.find()
方法的查询文档),然后应用指定的聚合管道。如果更新文档和查询文档均未指定 _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()
在使用 upsert()
和多文档更新方法 Bulk.find.update()
时,如果没有文档符合查询条件,则更新操作将插入单个文档。
Bulk.find.update()
方法的参数可以是:
仅包含更新操作符表达式的更新文档,或
聚合管道。
更新操作符表达式
var bulk = db.items.initializeUnorderedBulkOp(); bulk.find( { status: "P" } ).upsert().update( { $setOnInsert: { qty: 0, inStock: true }, $set: { status: "I", points: "0" } } ); bulk.execute();
接着,如果带 Bulk.find.upsert()
选项的更新操作执行插入,则该更新操作会插入一个文档(其字段和值来自 Bulk.find()
方法的查询文档),然后应用更新文档中的指定更新。如果更新文档和查询文档均未指定 _id
字段,则 MongoDB 将添加 _id
字段:
{ "_id": ObjectId("52ded81a98ca567f5c97aca1"), "status": "I", "qty": 0, "inStock": true, "points": "0" }
聚合管道 (Aggregation Pipeline)
更新方法可以接受聚合管道。例如,以下使用:
$replaceRoot
阶段,它提供与$setOnInsert
更新操作符表达式略微相似的行为,聚合变量
NOW
,解析为当前日期时间,可以提供与$currentDate
更新操作符表达式相似的行为。NOW
的值在整个管道中保持不变。要访问聚合变量,在变量前加上双美元符号$$
并用引号引起来。
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();
接着,如果带 Bulk.find.upsert()
选项的更新操作执行插入,则该更新操作会插入一个文档(其字段和值来自 Bulk.find()
方法的查询文档),然后应用聚合管道。如果更新文档和查询文档均未指定 _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") }