2

I'm looking to $push something into a nested array, of which the parent array matches a simple property condition:

Here's how my document looks:

{
  name: "Foo",
  boardBucket: {
    currentBoardId: 1234,
    items: [ <- looking to push into `boardItems` of an `item` in this Array
      { 
        boardId: 1234, <- that has `boardId: 1234` 
        boardItems: [ "barItem", "deyItem" ] <- Final Array I want to push to
      }
    ]
  }
}

So I'd like to push "fooItem" in boardItems of item that has boardId: 1234

Option 1: I can use dot notation and access by index

I can certainly do a $push by using dot.notation which uses the index of the item like so:

this.update({ '$push': {"boardBucket.items.0.boardItems": "fooItem" } });

But what if I don't know the index?

How can I push into boardItems of item with boardId: 1234 without using the indices (using the boardId instead)?


Note:

  • I'm using mongoose as the db driver
  • I'd like to avoid using mongoose's save() cause it tends to be buggy + it seems to keep a copy of the object locally which i'd like to avoid
  • Just direct update() mongo queries are what I'm after
  • I'd certainly like to avoid any type of whole-document fetching to perform this update as my documents are huge in size
2
  • You can use position operator ($). Commented Aug 19, 2016 at 9:43
  • @CetinBasoz thanks - It's not clear from the docs how that would work in this case - can you add a minimal example as an answer? Commented Aug 19, 2016 at 9:46

2 Answers 2

3

I think this should do the trick:

this.update(
  {"boardBucket.items": {$elemMatch: { boardId: "1234"}}},
  {'$push': {"boardBucket.items.boardItems": "fooItem" }}
);
Sign up to request clarification or add additional context in comments.

6 Comments

@CetinBasoz answer is more precise. My approach would push in to every boardBucket items array that has the "boardId": "1234".
That's exactly what I want to do as well - for some reason it throws cannot use the part (items of boardBucket.items.boardId) to traverse the element
I think you're missing a curly bracket after {$elemMatch: { boardId: "1234"}}, , should be {$elemMatch: { boardId: "1234"}}},
hate to be a pest but it doesn't seem to work - Although the query (with my corrected } addition) runs and returns nModified : 1, it doesn't seem to add "fooItem" anywhere in the DB (checked the entire DB in case it get's erroneously added somewhere else) - Note that the boardId's definitely match so that's not the problem - any ideas?
I confirm that: {'$push': {"boardBucket.items.boardItems": "fooItem" }} works
|
2

(Sorry for not sampling in the first place, was on a rush then)

db.myDb.insert({
  name: "Foo",
  boardBucket: {
  currentBoardId: 1234,
    items: [ 
      { 
        boardId: 1234, 
        boardItems: [ "barItem", "deyItem" ] 
      },
      { 
        boardId: 1235, 
        boardItems: [ "dontPushToThisOne" ] 
      }
    ]
  }
});

db.myDb.insert({
  name: "Foo2",
  boardBucket: {
    currentBoardId: 1236,
    items: [ 
      { 
        boardId: 1236, 
        boardItems: [ "dontPushToThisOne" ] 
      }
    ]
  }
});


db.myDb.update( 
   { "boardBucket.currentBoardId":1234,
     "boardBucket.items.boardId":1234},
   { "$push" : {"boardBucket.items.$.boardItems":"fooItem"} }, {multi:1} );

2 Comments

Awesome - Strangely enough I'm getting this error however: cannot use the part (items of boardBucket.items.boardId) to traverse the element ({items: [ { boardId: "147813751944",", _id: ObjectId('57b6da3fb0fcf466044a4c20')} ]}) - Is it because items is an array?
That may be mongoose specific, I don't use it. I wrote and tested the code in default mongo shell. (you use the quotes around it, right?)

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.