MongoDB中replaceOne()和updateOne()有什么区别?

85

MongoDB批量操作有两个选项:

  1. Bulk.find.updateOne()

    向批量操作列表中添加单个文档更新操作。该操作可以替换现有文档,也可以更新现有文档的特定字段。

  2. Bulk.find.replaceOne()

    向批量操作列表中添加单个文档替换操作。使用Bulk.find()方法指定确定要替换哪个文档的条件。Bulk.find.replaceOne()方法将替换限制为单个文档。

根据文档,这两种方法都可以替换匹配的文档。我理解正确吗,updateOne()是更通用的方法,既可以像replaceOne()一样精确替换文档,也可以仅更新其特定字段吗?

3个回答

126

使用 replaceOne() 可以替换整个文档,而使用 updateOne() 可以更新字段。

由于 replaceOne() 替换整个文档,因此不包含在新文档中的旧文档字段将会丢失。使用 updateOne() 可以添加新字段而不会失去旧文档中的字段。

例如,如果您有以下文档:

{
   "_id" : ObjectId("0123456789abcdef01234567"),
   "my_test_key3" : 3333
}

使用:

replaceOne({"_id" : ObjectId("0123456789abcdef01234567")}, { "my_test_key4" : 4})

导致结果:

{
   "_id" : ObjectId("0123456789abcdef01234567"),
   "my_test_key4" : 4.0
}

使用:

updateOne({"_id" : ObjectId("0123456789abcdef01234567")}, {$set: { "my_test_key4" : 4}})

导致结果为:

{
   "_id" : ObjectId("0123456789abcdef01234567"),
   "my_test_key3" : 3333.0,
   "my_test_key4" : 4.0
}

请注意,在使用updateOne()时,您可以在文档上使用更新运算符


3
你的问题是什么意思?“改变架构”是什么意思? - caub
2
使用replace可以用相同的参数替换文档为新的文档。而使用update则可以添加/删除组成文档的参数。 - Hughzi
3
好的,所以将_id始终更改为其他内容。 - caub
嗨,我刚刚尝试了当前版本的c#驱动程序2.4.4。@caub:替换不会改变“_id”。@Hughzi:我能够用更多和更少的字段替换文档。那么你所说的“更改模式”是什么意思? - BooFar
2
@BooFar 噢,抱歉,我完全错了。.replace(One) 用提供的新文档覆盖整个文档,但保留 _id。因此,它可能会更改该文档中字段的数量。通常,您可以使用.updateOne 和 $set 来保留现有值。 - caub
经过一些实验,我发现updateOne()replaceOne()都不会更改_id,而且两者都可以更改模式(文档的属性)。据我所知,当使用相同的筛选器和包含所有所需属性的更新/替换文档时,updateOne(<filter>, {$set: <document>}replaceOne(<filter>, <document>)之间没有区别。 - Vince

17

replaceOne()替换整个文档,而updateOne()允许更新或添加字段。在使用updateOne()时,您还可以访问更新运算符,可可靠地对文档执行更新。例如,两个客户端可以在同一文档的同一字段上“同时”增加值,并且两个增量将被捕获,而使用替换,则一个可能会覆盖另一个,从而潜在地丢失一个增量。

由于replaceOne()替换整个文档,未包含在新文档中的旧文档中的字段将丢失。使用updateOne(),新字段可添加而不会丢失旧文档中的字段。

例如,如果您有以下文档:

{
   "_id" : ObjectId("0123456789abcdef01234567"),

   "my_test_key3" : 3333
}

使用:

replaceOne({"_id" : ObjectId("0123456789abcdef01234567")}, { "my_test_key4" : 4})

结果是:

{
   "_id" : ObjectId("0123456789abcdef01234567"),
   "my_test_key4" : 4.0
}

使用:

updateOne({"_id" : ObjectId("0123456789abcdef01234567")}, {$set: { "my_test_key4" : 4}})

导致结果:

{
   "_id" : ObjectId("0123456789abcdef01234567"),
   "my_test_key3" : 3333.0,
   "my_test_key4" : 4.0
}

-5

db.collection.replaceOne()db.collection.updateOne()的功能完全相同。

主要区别在于,db.collection.replaceOne()编辑的数据需要来回传输到服务器,而db.collection.UpdateOne()仅请求过滤后的数据而不是整个文档!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接