Alistair Hardy
Alistair Hardy

Reputation: 465

findOneAndUpdate nested object in array

Trying to use findOneAndUpdate() to change an object inside an array within MongoDB. The documentation for mongoDB's nodeJS driver isn't clear to me. The document looks like this:

{
  _id:ObjectID(),
  some: string,
  body: string,
  steps:[
   [0]{name: "foo", state:"Q"},
   [1]{name: "bar", state:"Q"},
   [n]{name: "fooBar", state:"Q"}
 ]
}

I need to lookup the steps name (foo) and set it's state to P (for in progress) and then to C (for complete) when the task has been executed or E when it errors.

I'll then need to also grab the name of the next step to.

Finding the document isn't hard as I will have the _id already, it's the update portion that's getting me.

EDIT: This is what I've got so far

  async msg => {
    const _id = msg.content.toString();
    const id = new objectId(_id);
    logger.info(`${name} consumer - Recieved new task, fetching details`, {
      id
    });
    try {
      const jobDetails = await collection.findOneAndUpdate(
        { _id: id },
        {
          /**/
        }
      );
      await consumer.task(jobDetails);
    } catch (e) {}
  },

It's the framework for a rabbitMQ consumer

Upvotes: 7

Views: 9747

Answers (1)

Daniyal Lukmanov
Daniyal Lukmanov

Reputation: 1229

I don't know how would you choose wich letter to set - P, C or E, because it is not quite clear, but for replacing a value in mongoDB it would look like this (let's say for 'P'):

myCollection.findOneAndUpdate({"_id": docId, "steps.name": "foo"},
    {$set: {"steps.$.state": "P"}})
  1. Find the document you need to change.
  2. Find the object inside the array "steps.name": "foo". And you get the position of that object in array.
  3. You're setting new value for the object's property ( $ reflects the position).

Upvotes: 13

Related Questions