2
votes

I am using mongodb to insert and update some documents in some collection. When I update a document, I want to get the modified fields only. I can get the complete new document (including the modified fields) by using the returnOriginal option for updates, but it gives me all the properties.

From the docs:

returnOriginal | optional | When false, returns the updated document rather than the original. The default is true

My code is:

let result = await db.myCollection.findOneAndUpdate(
        {_id: ObjectId('5a2451399054bf000453c332')}, 
        data,
        {returnOriginal: true}
    );

where data can be either one field, or multiple fields, for example:

let data = {field1: 'newValue1'};

or

let data = {field1: 'newValue1', field2: 'newValue2'};

I would want to get those fields only, but the result of the update is giving me the entire object, including the _id property and all others, even if they weren't modified.

What I'm looking for is an easy way (a mongodb function or property would be ideal) to get only the modified fields, if there is such a way, rather than comparing both objects (before and after).

Using mongodb node driver:

"mongodb": "^3.1.6"
1
MongoDB doesn't have such a function unfortunately, you would need to do the comparison using a utility library like lodash or write your own custom function to check the before and after documentschridam

1 Answers

0
votes

You can do something like this

Create a key value pair for the keys you are passing with the value equal to 1 to use in projection.

var keys = {}
let data = { field1: 'newValue1', field2: 'newValue2' }
function setUsers(data) {
  for (var k in data) {
    if (data.hasOwnProperty(k)) {
      keys[k] = 1
    }
  }
  return keys
}
const projection = setUsers(data)

and then use projection in the query to limit the fields

db.myCollection.findOneAndUpdate(
  { _id: ObjectId('5a2451399054bf000453c332') }, 
  data,
  { returnOriginal: true, projection }
)