Node.js: "returnNewDocument: true" not working

I’m trying to return the updated or inserted document from the upsert operation.
setting, “returnNewDocument: true” is not working

I also have this scheme static-analysis issue when setting that option…
No overload matches this call

example code:
const r = await client.db(dbName).collection(collName).findOneAndUpdate(objFilter, { objToUpdateOrInsert } }, { upsert: true, returnNewDocument: true });

1 Like

Hi @Melody_Maker,

I gave it a try I was able to do it. Here is my sample code:

const { MongoClient } = require("mongodb");

const uri = "mongodb://localhost/test?retrywrites=true&w=majority";

const client = new MongoClient(uri, { useUnifiedTopology: true });

async function run() {
 try {
   await client.connect();

   const database = client.db('test');
   const collection = database.collection('coll');

   const filter = { title: 'Back to the Future' };
   const update = { $inc: { 'score': 10 }};
   const doc1 = await collection.findOneAndUpdate(filter, update, { upsert: true, returnOriginal: false });
   const doc2 = await collection.findOneAndUpdate(filter, update, { upsert: true, returnOriginal: false });

   console.log(doc1);
   console.log(doc2);
 } finally {
   await client.close();
 }
}
run().catch(console.dir);

Here is the result I get:

{
  lastErrorObject: { n: 1, updatedExisting: false, upserted: 5ff7970200ba0cc6b74ca81c },
  value: {
    _id: 5ff7970200ba0cc6b74ca81c,
    title: 'Back to the Future',
    score: 10
  },
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1610061570 },
    signature: { hash: [Binary], keyId: 0 }
  },
  operationTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1610061570 }
}
{
  lastErrorObject: { n: 1, updatedExisting: true },
  value: {
    _id: 5ff7970200ba0cc6b74ca81c,
    title: 'Back to the Future',
    score: 20
  },
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 3, high_: 1610061570 },
    signature: { hash: [Binary], keyId: 0 }
  },
  operationTime: Timestamp { _bsontype: 'Timestamp', low_: 3, high_: 1610061570 }
}

As you can see above, even on the first findOneAndUpdate against an empty collection, I get the resulting document rather than “null”. And on the second call, I get score = 20 which proves again that it works because I get the result of the second operation (10+10).

As you probably saw already, the correct parameter is returnOriginal rather than returnNewDocument. You can checkout all the other parameters - including this one - in the MongoDB Node.js documentation for findOneAndUpdate.

Often the Mongo Shell methods and the Node.js API look alike, but sometimes, like in this case, they actually differ for some obscur reasons.

Cheers :smiley:,
Maxime.

1 Like

Thanks Maxime, works.

Saves me from doing…

// let id;
// if (isNil(r.value)) {
// id = r.lastErrorObject && r.lastErrorObject.upserted; //the newly inserted PK
// l(“was inserted”, id);
// } else {
// id = r.value._id; //return update data;
// l(“was updated”, id);
// }
// return await client.db(dbName).collection(collName).findOne({ _id: new ObjectID(id) });

If you went along with doing the updateOne and then a findOne operation right after, it’s not a single atomic operation anymore like findOneAndUpdate.

So if the “all mighty power of multi-threading” allows another write operation after your updateOne but before your findOne, you might have surprising results.

That’s the point of having findOneAndUpdate in the first place :smiley: !

Glade I was here to save the day :sun_with_face: !

Cheers,
Maxime.

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