在 MongoDB 中保存和插入的区别是什么?

在 MongoDB 中保存和插入的区别是什么? 看起来都一样

db.users.save({username:"google",password:"google123"})


db.users.insert({username:"google",password:"google123"})
100527 次浏览

插入或更新文档。

insert只进行插入。

但是在您的示例中,它将执行相同的操作,因为 save 中提供的文档没有 _id字段。

正如您在这里看到的,save 方法实际上将执行一个 upsert (如果找到文档,则更新,否则插入) :

Http://docs.mongodb.org/manual/reference/method/db.collection.save/#db.collection.save

插入就是这样,直接插入。

保存 Vs 插入:

在给定的示例中,行为本质上是相同的。

如果使用“ _ id”参数传递 save,则其行为会有所不同。

为了保存,如果文档包含 _id,它将在 _id字段上查询集合,如果没有,它将插入。

如果文档不存在具有指定 _ id 值的文档,save ()方法将使用文档中的指定字段执行插入操作。

如果存在具有指定 _ id 值的文档,save ()方法将执行更新,将现有记录中的所有字段替换为文档中的字段。


保存 vs 更新 :

update 修改与查询参数匹配的现有文档。如果没有这样的匹配文档,那就是 upsert出现在图片中的时候。

  • upsert : false: 如果没有这样的文档,什么也不会发生
  • upsert : true: 新文档创建的内容相当于查询参数和更新参数

save : 不允许任何查询参数。如果 _id存在,并且有一个匹配的文档具有相同的 _id,它将替换它。当 no _ id 指定/no 匹配文档时,它将文档作为新文档插入。

就甲骨文而言: Mongo insert = > Oracle insert Mongo save = > Oracle merge

如果您试图使用“ insert”和以前在同一集合中使用的 ID,则会得到一个重复的键错误。如果将“ save”与已经在同一集合中的 ID 一起使用,它将被更新/覆盖。

如果你想做一个真正的更新,我建议使用“更新”。如果使用已在集合中的相同 ID 保存,则更新将不会以 Save 的方式进行覆盖。

例如,您有两个字段“ x”和“ y”,并且希望同时保留这两个字段,但是需要更改“ x”的值。如果您选择了“ save”命令,并且没有在前一个值中包含 y,或者在保存中根本没有 y,那么 y 将不再有相同的值或者在那里。但是,如果选择使用 $set 进行更新,并且在更新语句中只包含 x,则不会影响 y。

考虑下面的文档

{ "_id" : 1, "domainName" : "test1.com", "hosting" : "hostgator.com" }

如果 db 已经包含具有 _ id: 1的文档,则

保存操作将像下面这样引发异常

E11000 duplicate key error index ...........

当插入操作时,将覆盖文档。

举个例子

拯救苹果

db.fruit.save({"name":"apple", "color":"red","shape":"round"})
WriteResult({ "nInserted" : 1 })


db.fruit.find();


{
"_id" : ObjectId("53fa1809132c1f084b005cd0"),
"color" : "red",
"shape" : "round",
"name" : "apple"
}

用先前保存的 apple 的 _ id 保存一个 apple

db.fruit.save(
{"_id" : ObjectId("53fa1809132c1f084b005cd0"),"name":"apple",
"color":"real red","shape":"round"})


WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

现在我们保存的苹果有了,颜色从红色更新为真正的红色

db.fruit.find();
{
"_id" : ObjectId("53fa1809132c1f084b005cd0"),
"color" : "real red",
"shape" : "round",
"name" : "apple"
}

用 _ id 保存一个苹果

db.fruit.save({"_id" : ObjectId("55551809132c1f084b005cd0"),
"name":"apple", "color":"real red","shape":"round"})


WriteResult({ "nMatched" : 0, "nUpserted" : 1,
"nModified" : 0, "_id": 55551809132c1f084b005cd0 })

苹果被插入,因为没有苹果用相同的对象 ID 做一个更新

插入一个橙子

db.fruit.insert({"name":"orange", "color":"orange","shape":"round"})
WriteResult({ "nInserted" : 1 })

橙色插入

db.fruit.find();
{
"_id" : ObjectId("53fa1809132c1f084b005cd0"),
"color" : "real red",
"shape" : "round",
"name" : "apple"
}
{
"_id" : ObjectId("53fa196d132c1f084b005cd7"),
"color" : "orange",
"shape" : "round",
"name" : "orange"
}
{
"_id" : ObjectId("55551809132c1f084b005cd0"),
"color" : "real red",
"shape" : "round",
"name" : "apple"
}

因此,如果提供了对象 id,那么 save 将充当更新,前提是对象 id 已经存在,否则它将执行插入操作。

让我们考虑以下两种情况:-

1)在 doc 中使用 _ id。

2) doc 中没有 _ id。

                        Save ()
/     \
/       \


Having _id     Not Having _id


->In this case save will do    ->  It will do normal insertion
upsert to insert.Now             in this case as insert() do.
what that means, it means
take the document and replace
the complete document having same
_id.

让我们考虑这里插入的两种情况:-

1)在集合中具有 doc 的 _ id。

2)在集合中没有 doc 的 _ id。

                        Insert()
/        \
/          \


Doc Having _id in collection    Doc Not Having _id
->  E11000 duplicate key     ->Insert a new doc inside the collection.
error index:

db.<collection_name>.save(<Document>)等效于 InsertOrUpdate 查询。

db.<collection_name>.insert(<Document>)只等同于插入查询。