2016-03-01 121 views
3

我对mongodb很陌生,而且我有点迷路。如果子文档值不存在,Mongo DB插入子文档

我有蒙戈DB收集,看起来像这样:

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

我希望能够当名犯规存在插朋友数组中的新元素和孩子元素到新阵列。

伪代码将是

If Directory.find id.friends.name = true

update and add a new children document {name:"sarah",age:5}

else

make a new friend element with a new children subdocument

的研究很多后人们似乎都推荐使用的$存在,但我可以找不到在子文档中使用它的方法

我已经想出了这一点,但它不是真正的工作,我想知道我怎么能使用我的if else stament:

db.Directory.find({_id:id},{friends.name:"foo", {"$exists": True}}) 

实际查询

db.Directory.update(
    { _id: id, 'friends.name': "foo" }, 
    {$push: {'friends.$.children': {name:"x",age:"yy"}}} 
) 

如果它不存在:

db.Directory.insert(
    { _id: id, 'friends.name': "foo" }, 
    {$push: {'friends.$.children': {name:"x",age:"yy"}}} 
) 

但它不是真的工作,我不知道是否有什么东西克在我的公式,因为它是从研究的很多试验和错误。 我也不知道是否正确的方法来做到这一点,因为我无法找到子文档上存在的任何值,并计划尝试执行Find()搜索存储值,然后测试true或者在JS中产生更新/插入调用的结果为false。

希望有人能帮助

编辑: 比方说,我想添加{名字:约翰,年龄:15}到朋友的名字:1

friends : [{name:1,children:[{name:sarah,age:12}]}] 

我想输出到是

friends : [{name:1,children:[{name:sarah,age:12},{name:john,age:15}]}] 

,或者如果名称1犯规存在

friends : [] 

让这个它输出

friends : [{name:1,children:[{name:john,age:15}]}] 

更新例如:

情况之一:

friends : [] 

我添加了一个新朋友的名字 “乔希” 有一个孩子莎拉,12岁的我得到:

friends : [{name:"josh",children:[{name:sarah,age:12}]}] 

这是完美的。

Now i add a new friend name 2 with children tom 15. 

什么也没有发生。

后,我想添加一个新的子乔希,邓肯15岁

我得到:

friends : [{name:"josh",children:[{name:timmy,age:12}]}] 

和萨拉disapeared。

回答

2

请尝试通过Bulk operation来完成,通过$addToSet运营商添加一个新朋友并通过$set运营商更新好友,在您更清楚地提出问题后进行更新。

var bulk = db.Directory.initializeOrderedBulkOp(); 

// if `friends` is `[]`, push the empty children firstly through addToSet 
bulk.find({_id: id, 'friends.name': {$exists: false}}).updateOne(
    {$addToSet: {friends: {name: 1, children: []}}); 

// if we find the match friend, update this one through `$set` 
bulk.find({_id: id, 'friends.children.name': 'john'}).updateOne(
    {$set: {'friends.$.children': {name: 'john', age: 22}}}); 

// if we cannot find match friend, insert the new one through `$addToSet` 
bulk.find({_id: id, 'friends.children.name': {$ne: "john"}}).updateOne( 
    {$addToSet: {'friends.0.children': {name: 'john', age: 12}}}); 

bulk.execute(); 
+0

感谢您的帮助。那么,“nameinput”可以是一个js(string)变量吗?另外,第一个表达式是否将新元素{name:x,age:yy}推送到friends.name = name childrens输入数组(用户可以有多个childrens)? – user697

+0

@ user697,是的,“nameinput”可以是一个js(string)变量。 '$ set'只是更新名字的老朋友是'nameinput'。而'addToSet'会将新朋友加入'friends'数组,只有插入的值不会存在于'friends'数组中。 – zangw

+0

@ user697,很好的捕获,我会修复它... – zangw