7

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

4
  • Show us the code you're working on Commented Jun 10, 2019 at 13:18
  • Added existing code, though it's incomplete. The area I need is in the /* */ Commented Jun 10, 2019 at 13:26
  • So basically you did nothing in terms of writing the update query apart from stating that docs are not clear. Sounds like "write it for me" question. Take a look at docs.mongodb.com/manual/reference/method/… it has some almost copy-pasteable examples for your usecase. Commented Jun 10, 2019 at 13:34
  • No, I'd read that, but I if you don't understand the documentation, it's hard to apply it to your use case. Commented Jun 10, 2019 at 14:02

1 Answer 1

13

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).
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that did the trick. I know when to set each state. P is set when the consumer receives the task, C when it completes the job and E when it errors (so in the catch(e){...} ).
thanks, dude! I was looking for a solution like this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.