173

Mongo DB中的保存和插入有什么区别?两者看起来都一样

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

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

9 回答 9

168

保存与插入:

在您给定的示例中,行为基本相同。

save如果使用“_id”参数传递,则行为不同。

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

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

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


保存与更新

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

  • upsert : false: 当不存在这样的文件时什么都不会发生
  • upsert : true: 创建新文档,其内容等于查询参数和更新参数

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

于 2013-04-25T08:26:10.087 回答
107

让我们考虑这里的两种情况以进行保存:-

1)在文档中有_id。

2) 文档中没有 _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) 在集合中有 _id 的文档。

2) 集合中没有 _id 的文档。

                        Insert()
                       /        \
                      /          \

   Doc Having _id in collection    Doc Not Having _id 
  ->  E11000 duplicate key     ->Insert a new doc inside the collection.
      error index:       
于 2015-03-31T05:59:49.060 回答
38

save插入或更新文档。

insert只做一个插入。

但在你的情况下,它会做同样的事情,因为保存中提供的文档没有_id字段。

于 2013-04-25T08:21:09.277 回答
14

通过举例

拯救一个苹果

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

db.fruit.find();

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

使用先前保存的苹果的 _id 保存一个苹果

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 })

Apple 被插入,因为没有具有相同对象 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,则保存将充当更新,前提是该对象 ID 已经存在,否则它会执行插入。

于 2014-08-24T17:12:05.013 回答
11

如果您尝试将“插入”与以前在同一集合中使用的 ID 一起使用,您将收到重复键错误。如果您对已在同一集合中的 ID 使用“保存”,它将被更新/覆盖。

如果您要进行真正的更新,我建议您使用“更新”。如果您使用集合中已有的相同 ID 进行保存,则更新不会像 Save 那样覆盖。

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

于 2014-05-26T02:49:08.400 回答
6

正如您在此处看到的,save 方法本质上将执行 upsert(如果找到文档则更新,否则插入):

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

插入就是这样,一个直的插入。

于 2013-04-25T08:21:33.820 回答
3

考虑以下文件

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

如果 db 已经包含 _id:1 的文档,则

保存操作会抛出如下异常

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

而作为插入操作的地方,只会覆盖文档。

于 2014-06-03T09:01:18.367 回答
1

在 ORACLE 方面: mongo insert => Oracle insert mongo save => Oracle merge

于 2014-02-17T12:05:04.507 回答
1

db.<collection_name>.save(<Document>)相当于 InsertOrUpdate 查询。

而,db.<collection_name>.insert(<Document>)相当于只是插入查询。

于 2015-12-15T07:11:33.957 回答