2016-03-01 154 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