Update document only if new data differs from current data

Hi,

Is there an easy way to compare new data to the existing data and only update the fields that don’t match?

Our scenario is a typical authentication flow for users.
When a user signs up, for example with Google, the returned user object includes name, email and picture:

{
  given_name: "John",
  family_name: "Doe",
  email: "johndoe@gmail.com",
  picture: "https://lh3.googleusercontent.com/a-sdfgsfdghskfg9453453llsdfs"
}

This user object is then saved to MongoDB.
A cookie or token is created and the user can access the backend API as desired.
On each request, the cookie/token is verified with Google and a new user object is returned.

My goal is to compare the user data on the DB with the data returned from Google and just update the fields if they changed, for example maybe the picture changed.

I can do the comparison on our backend server, but if there is a method for Mongo to compare and update the fields, that would be first prize.

Appreciate any assistance.

Hello @Stephan_06935, here is a possible way of doing the update. I am assuming that the “new data” will (and must) have all the four fields, for example:

var new_data = 
  {
      given_name: "John",
      family_name: "Doe",
      email: "johndoe@gmail.com",
      picture: "https://lh3.googleusercontent.com/xyz-123"    // <=== changed picture
}

The update operation:

db.collection.updateOne(
{ 
  _id : ObjectId("61d32d82b6cc0e892d912c8c"),
  $or: [ 
      { given_name: { $ne: new_data.given_name }},
      { family_name: { $ne: new_data.family_name }},
      { email: { $ne: new_data.email }},
      { picture: { $ne: new_data.picture }}
  ]
},
{
  $set: {
      given_name: new_data.given_name,
      family_name: new_data.family_name,
      email: new_data.email,
      picture:  new_data.picture
  }}
)

This works with the new_data having all the fields that might get changed for the update, including the unchanged fields. In case there are no changes for any of he fields, then the update doesn’t happen.

3 Likes

Hi @Prasad_Saya,

Thank you so much. This definitely helps.
Appreciate your effort!

I would add another option,
take out those fields you want to examine and apply a consistent hash function and keep it as
a property, and for next updates you can run the same hash function on incoming data,
this way you may only compare one property

db.collection.updateOne(
{  
     hashed_value: { $ne: new_data.hashed_value }
},
{
  $set: {
      given_name: new_data.given_name,
      family_name: new_data.family_name,
      email: new_data.email,
      picture:  new_data.picture
  }}
)

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.