66

MongoDB bulk operations have two options:

  1. Bulk.find.updateOne()

    Adds a single document update operation to a bulk operations list. The operation can either replace an existing document or update specific fields in an existing document.

  2. Bulk.find.replaceOne()

    Adds a single document replacement operation to a bulk operations list. Use the Bulk.find() method to specify the condition that determines which document to replace. The Bulk.find.replaceOne() method limits the replacement to a single document.

According to the documentation, both of these two methods can replace a matching document. Do I understand correctly, that updateOne() is more general purpose method, which can either replace the document exactly like replaceOne() does, or just update its specific fields?

Mike B.
  • 10,955
  • 19
  • 76
  • 118

3 Answers3

83

With replaceOne() you can only replace the entire document, while updateOne() allows for updating fields.

Since replaceOne() replaces the entire document - fields in the old document not contained in the new will be lost. With updateOne() new fields can be added without losing the fields in the old document.

For example if you have the following document:

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

Using:

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

results in:

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

Using:

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

results in:

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

Note that with updateOne() you can use the update operators on documents.

Jurgen Strydom
  • 2,390
  • 19
  • 29
Hughzi
  • 1,862
  • 15
  • 27
  • 3
    what do you mean with "change the schema"? – caub Oct 29 '16 at 11:10
  • 2
    replace replaces a document with a new one, using the same parameters. with update you can add/remove parameters which make up the document. – Hughzi Oct 31 '16 at 12:35
  • 3
    ah ok, so replace always change `_id` – caub Oct 31 '16 at 13:09
  • Hi, I just tried it with the current version of the c# driver 2.4.4. @caub: replace doesn't change the `_id`. @Hughzi: I was able to replace a document with more and with less fields. So what did you mean with "change the schema"? – BooFar Jun 25 '17 at 06:13
  • 2
    @BooFar oh sorry yes, I was totally wrong, .replace(One) overwrites the whole document with the new one provided, but keeps _id. so it changes potentially the number of fields in that document. Usually you can use .updateOne and $set to keep existing values – caub Jun 25 '17 at 10:45
  • After a little bit of experimentation, I can see that neither `updateOne()` or `replaceOne()` changes `_id` and either one can change the schema (the properties of the document). As far as I can tell, when using the same filter and a update / replacement document that contains all the desired properties, there's no difference between `updateOne(, {$set: }` and replaceOne(, ). – Vince Mar 21 '18 at 08:55
13

replaceOne() replaces the entire document, while updateOne() allows for updating or adding fields. When using updateOne() you also have access to the update operators which can reliably perform updates on documents. For example two clients can "simultaneously" increment a value on the same field in the same document and both increments will be captured, while with a replace the one may overwrite the other potentially losing one of the increments.

Since replaceOne() replaces the entire document - fields in the old document not contained in the new will be lost. With updateOne() new fields can be added without losing the fields in the old document.

For example if you have the following document:

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

   "my_test_key3" : 3333
}

Using:

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

results in:

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

Using:

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

results in:

{
   "_id" : ObjectId("0123456789abcdef01234567"),
   "my_test_key3" : 3333.0,
   "my_test_key4" : 4.0
}
Jurgen Strydom
  • 2,390
  • 19
  • 29
-1

db.collection.replaceOne() does exactly the same thing as db.collection.updateOne().

The main difference is that db.collection.replaceOne()'s data that are being edited will have to go back and forth to the server, whereas db.collection.UpdateOne() will request only the filtered ones and not the whole document!

ejderuby
  • 718
  • 5
  • 20
Evangelos
  • 57
  • 8