2011-07-19 92 views
4

中我有以下結構添加屬性,以嵌套的數組MongoDB的文檔

> db.user.find().limit(1); 
{ "_id" : "1", "foo" : { "bars" : [ 
    { 
     "name" : "bar1" 
    }, 
    { 
     "name" : "bar2" 
    }, 
], ... }, ... } 

我想一個新的屬性添加到每個bar一個MongoDB的文檔。我的腳本迭代了bars數組,但我無法獲得新的屬性,我該怎麼做?

var users = db.user.find({"foo.bars":{$exists:true}}); 

users.forEach(function(user) { 
    user.foo.bars.forEach(function(bar) 
    { 
     printjson(bar); 
     //how can I specify the current 'bar' in this update? 
     //db.experience.update({_id: user._id}, {$set: {"what goes here?" : "newbarValue"}}); 
    }); 
}); 
+0

是否確實「想一個新的屬性添加到每個欄」實際工作?特別是你想在'user.foo.bars。$ {bar}'中使用'user',那麼'$ {bar}'應該做什麼?難道是你試圖在沒有檢查過的情況下發明新的語法嗎?對於想這不是有效的語法,你會發現它的註釋,我想表達我的意圖 –

+0

「user.foo.bars $ {}吧。」表示?。這裏沒有什麼用處,你不能這樣做: – markdsievers

回答

10

所以說,傳道人:

var users = db.user.find({"foo.bars":{$exists:true}}); 

users.forEach(function(user) { 
    var id = user._id; 

    var foo_bars = user.foo.bars; 
    var new_foo_bars = []; 

    for(var i = 0; i < foo_bars.length; i++) { 
     var foo_bar = foo_bars[i]; 
     foo_bar['newkey'] = 'newvalue'; 
     new_foo_bars.push(foo_bar); 
    } 

    db.user.update({"_id":id}, {$set:{"foo.bars":new_foo_bars}}); 
}); 
+0

+1準確的解決方案我會實施 – Sammaye

+1

AFAIK,使用forEach不能很好地擴展,只要更新運行就會鎖定整個數據庫。 –

+0

很好的答案,但有沒有辦法避免使用foreach?我使用上述方法從另一個集合中檢索變量,並在呈現模板之前將其添加到集合的結果集中。在sql中,我會做一個ID連接有沒有類似的mongo? – Thordin9

0

您必須逐個更新嵌套文檔的每個元素。使用位置運算符'$'將不起作用,因爲它只能在第一場比賽中工作(如記錄)。

+0

沒有什麼用處,但由於 – markdsievers

+0

- 東西實際上工作 –

+0

「你必須單獨更新嵌套文檔的每個元素。 「這本質上是我在問怎麼做 - 重申它作爲一個答案是沒有用的,指點我相關的文檔或者提供一段僞代碼會很棒,花一個小時試圖在來這裏之前把它搞定 - 所以我是失望的它下來投票,並建議香港專業教育學院沒有嘗試自我解決DOCO – markdsievers

1

我注意到,你是通過在JS的客戶端有數組滾動。

如果要形成從老一新的「酒吧」陣列,然後將其推入一個全新的價值,這將意味着你只能做一個DB調用和代碼也相當考究。

如果MongoDB的不支持,一般最好是剛做在客戶端的工作。

+0

正確 - 你可以添加一個單一的項目下的數組元素之一與$設置不是所有的人。所以做客戶端。您可以通過本地主機在服務器上運行客戶端腳本,它應該表現得非常好。 –