Syntax for pipeline code in function?

Function code - this works and updates field nxt_plyr_clr = 100:

const match = { "gm_id": 11 };
const update = {
    '$set': { "nxt_plyr_clr" : 100 }
  };  
const options = { returnNewDocument: true };

return await context.services
    .get("mongodb-atlas")
    .db("db1")
    .collection("coll1")
    .findOneAndUpdate(match,  update , options)
  .then(updatedDocument => {
    if(updatedDocument) {
      console.log(`Successfully updated document: ${updatedDocument}.`)
    } else {
      console.log("No document matches the provided query.")
    }
    return updatedDocument
  })
  .catch(err => console.error(`Failed to find and update document: ${err}`))
    
};

This does not work the way I want it to so I think my syntax is wrong:

 const update = {
    '$set': { "nxt_plyr_clr" : "$gm_mv_cnt" }
  };

gm_mv_cnt is an existing field in this document with a value of 5, instead of the update producing:

"nxt_plyr_clr": 5,

I am getting:

"nxt_plyr_clr": "$gm_mv_cnt",

Hi @Mic_Cross,

Your $set expression is relying on a field path expression, which is supported in the aggregation $set operator, but not the update $set operator. To trigger this behavior, you need to perform a pipeline update.

Atlas Functions do not support pipeline updates in findOneAndUpdate calls at the moment. If you don’t need the atomic guarantees of findOneAndUpdate, you can instead perform an updateOne with a pipeline update followed by a findOne, like so:

const coll = context.services
  .get("mongodb-atlas")
  .db("db1")
  .collection("coll1")

await coll.updateOne(match, [update]) // note the "[]"; this is now a pipeline update
await coll.findOne(match)

Let me know if that works for you!

1 Like

Thank you for this great explanation - exactly what I needed to know.

Hello Mic:

Some corrections to your code:

const match = { "gm_id": 11 };
const update = {
  '$set': { "nxt_plyr_clr": 100 }
};
const options = { returnNewDocument: true };

try {
  const updatedDocument = await context.services
    .get("mongodb-atlas")
    .db("db1")
    .collection("coll1")
    .findOneAndUpdate(match, update, options);
  if (updatedDocument) {
    console.log(`Successfully updated document: ${updatedDocument}.`);
    return updatedDocument;
  } else {
    console.log("No document matches the provided query.");
    return null;
  }
} catch (err) {
  console.error(`Failed to find and update document: ${err}`);
  return null;
}

This is for better error handling and detection if there’s issues with the collection as well.

const match = { "gm_id": 11 };
const update = {
  '$set': { "nxt_plyr_clr": 100 }
};
const options = { returnNewDocument: true };

try {
  const collection = context.services
    .get("mongodb-atlas")
    .db("db1")
    .collection("coll1");
  if (!collection) {
    console.log("Collection not found.");
    return null;
  }
  const updatedDocument = await collection.findOneAndUpdate(match, update, options);
  if (updatedDocument) {
    console.log(`Successfully updated document: ${updatedDocument}.`);
    return updatedDocument;
  } else {
    console.log("No document matches the provided query.");
    return null;
  }
} catch (err) {
  console.error(`Failed to find and update document: ${err}`);
  return null;
}

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