1 Question: Meteor/Mongo - add/update element in sub array dynamically

Question created on Sunday February 26, 2017

So I have found quite few related posts on SO on how to update a field in a sub array, such as this one here

What I want to achieve is basically the same thing, but updating a field in a subarray dynamically, instead of just calling the field name in the query. Now I also found how to do that straight in the main object, but cant seem to do it in the sub array.

Code to insert dynamically in sub-object:

_.each(data.data, function(val, key) {
  var obj = {};
  obj['general.'+key] = val;
  insert = 0 || (Documents.update(
    { _id: data._id },
    { $set: obj}
  ));
});

Here is the tree of what I am trying to do:

Documents: {
 _id: '123123'
 ...
 smallRoom:
  [
    _id: '456456'
    name: 'name1'
    description: 'description1'
  ],
  [
  ...
  ]
}

Here is my code:

// insert a new object in smallRoom, with only the _id so far 
var newID = new Mongo.ObjectID;
var createId = {_id: newID._str};
Documents.update({_id: data._id},{$push:{smallRooms: createId}})

And the part to insert the other fields:

_.each(data.data, function(val, key) {
  var obj = {};
  obj['simpleRoom.$'+key] = val;
  console.log(Documents.update(
    { 
      _id: data._id,    <<== the document id that I want to update
      smallRoom: { 
        $elemMatch:{
          _id : newID._str,   <<== the smallRoom id that I want to update
        }
      }
    },
    { 
      $set: obj
    }
  ));
});

Ok, having said that, I understand I can insert the whole object straight away, not having to push every single field.

But I guess this question is more like, how does it work if smallRoom had 50 fields, and I want to update 3 random fields ? (So I would NEED to use the _each loop as I wouldnt know in advance which field to update, and would not want to replace the whole object)

3
1 answer                              3                         

I'm not sure I 100% understand your question, but I think the answer to what you are asking is to use the $ symbol.

Example:

Documents.update(
    { 
      _id: data._id, smallRoom._id: newID._str
    },
    { 
      $set: { smallroom.$.name: 'new name' }
    }
);

You are finding the document that matches the _id: data._id, then finding the object in the array smallRoom that has an _id equal to newId._str. Then you are using the $ sign to tell Mongo to update that object's name key.

Hope that helps

1
Sunday February 26, 2017
source posted here