12

I have an object structure like this:

 {
    name: "...",
    pockets: [
        {
            cdate: "....",
            items: [...]
        }
        ...
    ]
 }

In an update operation, I want to add some records into the items field of the last pocket item. Using dot notation is the only way that I know to access a sub document, but I can't get what I want. So, I'm looking for something like these:

  • pockets.-1.items
  • pockets.$last.items

Is it possible to modify the last element? If yes, how?

4
  • Am I correct that you want to modify items, not fetch it? Commented May 22, 2012 at 18:50
  • Yes, you are correct. In fetching, I can use $slice operator. Commented May 22, 2012 at 18:52
  • I'm pretty sure this can't be done with a simple update unless you have some other way to match the last pocket. Commented May 22, 2012 at 19:04
  • Can you modify header to "..... in MongodB"? This is not clear. Commented May 21, 2019 at 12:06

2 Answers 2

3

I don't know of a way to do this using a single-line query. But you could select the record, update and then save it.

var query = <insert query here>;
var mydocs = db.mycollection.find(query);
for (var i=0 ; i<mydocs.length ; i++) {
    mydocs[i].pockets[pockets.length-1].items.push('new item');
    db.mycollection.save(mydoc);
}
Sign up to request clarification or add additional context in comments.

1 Comment

this may not be thread-safe as another process could have modified the array after the find and before the save.
3

I don't believe it is possible to do it atomically. There is a request for this functionality to be added to MongoDB.

If you can assure thread-safety in your application code, you could probably use a sequence of $pop from pockets array (that removes the last element from pockets) to variable p and then $addToSet to p.items, now you can $push p back into pockets. But if your application doesn't have a way to assure only one process may be doing this at one time, then another process could modify the array in the middle of those steps and you may end up losing that update.

You might also look into "Update if current" semantics here to see another way you can work around possible race by multiple threads issue.

Comments

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.