Update document with conditions

Hi,

I’m looking for a way to perform an update that adds/modifies the parameter “isShared” to true and if the queried document has no trasactionId parameter it adds this parameter too (with a mongoId). But if it exists, does not add it nor update it.

Chat gpt proposed something but it requires two trips to the DB, which is not optim, i think.

In other words: How can I convert the following code into another that avoids a previous check on the DB

Thanks!

const MongoClient = require('mongodb').MongoClient;

const { ObjectId } = require('mongodb');

const uri = "mongodb+srv://<username>:<password>@cluster.mongodb.net/test?retryWrites=true&w=majority";

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

async function shareDocument(documentId) {

  try {

    await client.connect();

    const collection = client.db("test").collection("documents");

    // check if the "transactionId" parameter exists

    const document = await collection.findOne({ _id: ObjectId(documentId), transactionId: { $exists: false } });

    if (!document) {

      // if the "transactionId" parameter exists, update the "isShared" parameter only

      await collection.updateOne({ _id: ObjectId(documentId) }, { $set: { isShared: true } });

    } else {

      // if the "transactionId" parameter does not exist, create it and update the "isShared" parameter

      await collection.findOneAndUpdate({ _id: ObjectId(documentId) }, { $set: { isShared: true, transactionId: new ObjectId() } });

    }

  } catch (err) {

    console.log(err);

  } finally {

    await client.close();

  }

}

Hi :wave: @kevin_Morte_i_Piferrer,

Welcome back to the MongoDB Community forums :sparkles:

Apologies for the late response.

To perform the desired operation while skipping the db check, you can rewrite the query as follows:

async function shareDocument(documentId) {
    try {
        const client = await MongoClient.connect(uri, { useNewUrlParser: true });
        const collection = client.db("test").collection("sample");
        const result = await collection.findOneAndUpdate(
            {
                _id: documentId,
                transactionId: { $exists: false }
            },
            {
                $set: { isShared: true, transactionId: new ObjectId() }
            }
        );
        if (!result.value) {
            await collection.updateOne(
                { _id: documentId },
                { $set: { isShared: true } }
            );
        }
    } catch (err) {
        console.log(err);
    } finally {
        await client.close();
    }
}

Here, I’ve used the findOneAndUpdate method with $exists + $set operator to add “transactionId” if it does not exist and update the “isShared” field. If findOneAndUpdate returns null, then I know that the document was not found and I can proceed with the updateOne method to set “isShared” to true.

Please alter and test the code above accordingly against a test environment to ensure it meets all your use case/requirement(s) before implementing it in production.

I hope it helps!

Best,
Kushagra

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