MongoDB upsert 解释

发布于

MongoDB中的许多更新操作都有可能成为更新插入。更新插入是插入和更新的组合。

它的工作原理如下:您根据筛选条件执行更新操作,如果有任何匹配项,则仅更新匹配的文档,如果没有匹配项,则插入一个新文档。

例

假设我们有一个名为 pets 的集合,其中包含以下文档:

{ “_id” : 1, “name” : “Wag”, “type” : “Dog” } { “_id” : 2, “name” : “Bark”, “type” : “Dog” } { “_id” : 3, “name” : “Meow”, “type” : “Cat” }

我们可以执行以下更新操作,将参数设置为 :upsert``true

db.pets.updateOne( 
    { name: "Wag" },
    { $set: { type: "Cow" } },
    { upsert: true }
    )

结果:

{ “acknowledged” : true, “matchedCount” : 1, “modifiedCount” : 1 }

在本例中,有一个匹配的文档(即有一个带有 的文档),因此匹配的文档已更新。没有插入任何内容。name: "Wag"

我们可以按如下方式验证这一点:

db.pets.find()

结果:

{ “_id” : 1, “name” : “Wag”, “type” : “Cow” } { “_id” : 2, “name” : “Bark”, “type” : “Dog” } { “_id” : 3, “name” : “Meow”, “type” : “Cat” }

第一个文档现在具有 的 。type``Cow

让我们再次使用 .但这一次,将没有匹配的文档要更新。upsert: true

db.pets.updateOne( 
    { name: "Bubbles" },
    { $set: { type: "Fish" } },
    { upsert: true }
    )

结果:

{ “acknowledged” : true, “matchedCount” : 0, “modifiedCount” : 0, “upsertedId” : ObjectId(“5fe1b4c8d9914101694100b7”) }

在此示例中,我们尝试查找一个有的文档,但没有找到任何文档。name: "Bubbles"

这次我们可以看到 是 ,也是 。这意味着没有更新任何现有文档。matchedCount``0``modifiedCount``0

我们还可以看到 a 被返回,这意味着文档被更新插入。upsertedId

让我们再看一下文档的集合:

db.pets.find()

结果:

{ “_id” : 1, “name” : “Wag”, “type” : “Cow” } { “_id” : 2, “name” : “Bark”, “type” : “Dog” } { “_id” : 3, “name” : “Meow”, “type” : “Cat” } { “_id” : ObjectId(“5fe1b4c8d9914101694100b7”), “name” : “Bubbles”, “type” : “Fish” }

我们可以看到插入/更新了一个新文档,并且它具有与上述相同的 ID。

发生更新插入是因为这次没有要更新的匹配文档(因此插入/更新插入了一个新的文档)。

如果我们没有设置 ,该文档就不会入。upsert: true

批量更新的更新插入

执行批量更新时,如果要指定 ,则需要将其与 一起使用。upsert: true``Bulk.find.upsert()

这可以与以下写入操作一起使用:

  • Bulk.find.replaceOne()
  • Bulk.find.updateOne()
  • Bulk.find.update()

语法是这样的:

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

例:

var bulk = db.pets.initializeUnorderedBulkOp();
bulk.find( { name: "Bruce" } ).upsert().replaceOne(
   {
     name: "Bruce",
     type: "Bat",
   }
);
bulk.execute();

结果:

BulkWriteResult({ “writeErrors” : [ ], “writeConcernErrors” : [ ], “nInserted” : 0, “nUpserted” : 1, “nMatched” : 0, “nModified” : 0, “nRemoved” : 0, “upserted” : [ { “index” : 0, “_id” : ObjectId(“5fe1c179d9914101694100dd”) } ] })

我们可以看到一个文档被更新了。我们还可以看到为该文档生成的内容。_id

现在,当我们查看集合中的文档时,我们可以看到已更新插入的新文档:

db.pets.find()

结果:

{ “_id” : 1, “name” : “Wag”, “type” : “Cow” } { “_id” : 2, “name” : “Bark”, “type” : “Dog” } { “_id” : 3, “name” : “Meow”, “type” : “Cat” } { “_id” : ObjectId(“5fe1b4c8d9914101694100b7”), “name” : “Bubbles”, “type” : “Fish” } { “_id” : ObjectId(“5fe1c179d9914101694100dd”), “name” : “Bruce”, “type” : “Bat” }