在Mongo DB中保存和插入有什么区别?


Answers:


146

保存与插入:

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

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

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

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

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


保存与更新

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

  • upsert : false :没有此类文档时,不会发生任何事情
  • upsert : true :新文档的创建内容等于查询参数和更新参数

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


8
两者都有不同的语法。Update接受多个参数({condition},{update to doc},upsert,multi),而save只接受一个参数(_id是条件参数的参数)。update可以接受任何条件,但save仅对条件具有条件限制_id字段。
拉胡尔2014年

1
从2.6版开始,save具有第二个参数,该参数采用表示写关注点的文档。docs.mongodb.org/manual/reference/method/db.collection.save
huggie 2014年

77

为了节省,让我们考虑这两种情况:

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的doc。

                        Insert()
                       /        \
                      /          \

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

10
下一级别的图表
John Spiteri

2
赞成为整洁地绘制和展示图表所花费的时间。
fanbondi

36

save 插入或更新文档。

insert 仅插入。

但是对于您而言,它将执行相同的操作,因为save中提供的文档没有_id字段。


13

通过举一个例子

保存一个苹果

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

苹果被插入,因为没有苹果具有相同的对象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已经存在,否则执行插入操作。


10

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

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

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



3

考虑以下文件

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

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

保存操作将引发如下异常

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

在哪里作为插入操作,将覆盖文档。


db.collection.save()如果数据库中已经存在具有相同_id的文档,则该方法将更新文档。如果数据库中已经存在具有相同_id的文档,则save方法将用新文档完全替换该文档。摘自Pro MongoDB开发书
杰克空白,

1

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


1

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.