Answers:
保存与插入:
在给定的示例中,行为基本相同。
save
如果使用“ _id”参数传递,则行为会有所不同。
为了保存,如果文档包含_id
,它将在_id
字段上查询查询集合,否则将插入。
如果不存在具有指定_id值的文档,则save()方法将对文档中的指定字段执行插入操作。
如果存在具有指定的_id值的文档,则save()方法将执行更新,将现有记录中的所有字段替换为文档中的字段。
保存与更新:
update
修改与您的查询参数匹配的现有文档。如果没有这样的匹配文档,那将upsert
是图片。
upsert : false
:没有此类文档时,不会发生任何事情upsert : true
:新文档的创建内容等于查询参数和更新参数save
:不允许任何查询参数。如果_id
存在,并且有一个相同的文档_id
,它将替换它。当未指定_id /没有匹配的文档时,它将作为新文档插入。
为了节省,让我们考虑这两种情况:
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:
通过举一个例子
保存一个苹果
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已经存在,否则执行插入操作。
如果尝试将“插入”与先前在同一集合中使用的ID结合使用,则会收到重复的键错误。如果将“保存”与同一集合中已经存在的ID一起使用,它将被更新/覆盖。
如果您要进行真正的更新,建议您使用“更新”。如果您使用集合中已有的相同ID进行保存,则更新不会以保存的方式覆盖。
例如,您有两个字段“ x”和“ y”,并且要保留两个字段,但要更改“ x”的值。如果您选择“保存”命令,并且不将y与先前的值包括在一起,或者在保存中根本没有y,则y将不再具有相同的值或在那里。但是,如果选择使用$ set进行更新,并且更新语句中仅包含x,则不会影响y。
正如您在此处看到的那样,save方法实际上将执行upsert(如果找到doc,则进行更新,否则插入):
http://docs.mongodb.org/manual/reference/method/db.collection.save/#db.collection.save
插入就是这样,直接插入。
考虑以下文件
{ "_id" : 1, "domainName" : "test1.com", "hosting" : "hostgator.com" }
如果db已经包含带有_id:1的文档,则
保存操作将引发如下异常
E11000 duplicate key error index ...........
在哪里作为插入操作,将覆盖文档。
db.collection.save()
如果数据库中已经存在具有相同_id的文档,则该方法将更新文档。如果数据库中已经存在具有相同_id的文档,则save方法将用新文档完全替换该文档。摘自Pro MongoDB开发书
db.<collection_name>.save(<Document>)
等效于InsertOrUpdate查询。
而,db.<collection_name>.insert(<Document>)
仅相当于插入查询。