1

I have mongo db collection that looks like this :

({
  _id:id ,
  createdAt: new Date(),
  name:name,
  friends : [{name:"tommy",children:[{name:"sarah",age:12}]}],
  dogs : [{}]
});

I would like to be able to insert a new element in the friends array if the name doesnt exist and a children element to that new array.

If i'm adding a new friend named john with a child nathaly , i'd like the output to be

({
  _id:id ,
  createdAt: new Date(),
  name:name,
  friends : [{name:"tommy",children:[{name:"sarah",age:12}]},{name:"john",children:[{name:"natahly",age:20}]}],
  dogs : [{}]
});

If friend tommy already exist i would like just the children to be added to the children array and the output to now be

({
  _id:id ,
  createdAt: new Date(),
  name:name,
  friends : [{name:"tommy",children:[{name:"sarah",age:12},{name:"newchild",age:99}]},{name:"john",children:[{name:"natahly",age:20}]}],
  dogs : [{}]
});

I've tried so many things already it's impossible to list.

currently i'm trying a mix of everything

  // if `friends` is `[]`, push the empty children firstly through addToSet
  var bulk = Directory.rawCollection().initializeUnorderedBulkOp();
  bulk.find({_id: id, 'friends.name': {$exists: false}}).updateOne(
 {$addToSet: {friends: {name: name_var, children: []}});
  Meteor.wrapAsync(bulk.execute)();
  // then Since previous step create the children array for said friend only if it doesn't already exist i'm just trying to update said friend with the new child
  Directory.update(
  { _id: id,"friends.name": name_var },
  { $push: { "friends.$.children": {name:"sarah",age:12}
  }}})

(i've also tried with "friends.children" instead of "friends.$.children" but i just get a different error)

And this should cover my three case but i'm having issues and i'm wondering if i'm going the right way. Any of you guys have any idea because this should at least work to add the children but it doesn't..

Errors : MongoError: The field 'friends.0.children' must be an array but is of type Object in document {_id: "0"} # when friends.$.children"

MongoError: cannot use the part (Friends of Friends.childrens) to traverse the element when friends.children"
user697
  • 233
  • 1
  • 7

1 Answers1

1

One way of doing it would be to,

  • Initialize the object you want to insert/update

The object can have multiple children inserted at once.

var obj = {name:"tommy",children:[{name:"ds",age:12},{name:"two",age:12}]};

The order of operations does not matter here.

var bulk = db.t.initializeUnorderedBulkOp();
  • Find and update only the children records that already have a sub document for the name.

use the $addToSet operator to maintain unique records, and $each to add more than one children at a time.

bulk.find({"friends.name":obj.name})
    .update({$addToSet:{"friends.$.children":{$each:obj.children}}});
  • Find and update those which do not have a sub document.

$push the entire object if a document doesn't have one.

bulk.find({"friends.name":{$ne:obj.name}})
    .update({$push:{"friends":obj}});
bulk.execute();
BatScream
  • 19,260
  • 4
  • 52
  • 68