2013-11-03 39 views
0

我有了,看起來像下面更新條目或添加到數組,如果項目不存在

{ "_id" : "MHBk8q96vpuRYrAdn", 
    "circles" : { 
     "guests" : 3, 
     "properties" : [  
      {  
       "position" : { "x" : 146, "y" : 70.5207970}, 
       "name" : "circle-1" 
      }, 
      {  
       "position" : { "x" : 200, "y" : 85}, 
       "name" : "circle-2" 
      } 
     ], 
     "tables" : 1 
    } 
} 

我需要能夠要麼更新圈子的位置的結構集合.properties.position(如果它按名稱存在),或者如果不存在,則添加一個新條目。例如,更新「circle-1」的位置,因爲它存在,但爲名稱和位置添加一個新的「circle-3」數組項。是否有可能實現這一目標?到目前爲止,我只能使用$ push推到數組上,並且我沒有成功地使用$(query)操作符。謝謝。

回答

2

由於MongoDB doesn't support upserts to arrays它可能會非常棘手。你可以嘗試類似如下:

var query = {}; 
new_circle = { "position" : { "x" : -1, "y" : -1}, "name" : "circle-1" }; 

db.foo.find(query).forEach(
    function(doc) { 

     // Find index of 'circle-1' 
     i = doc.circles.properties.map(
      function(el) { if (el.name == 'circle-1') return 1; else return -1;} 
     ).indexOf(1); 

     // Update if circle-1 in circles-properties 
     if (i != -1) { 
      doc.circles.properties[i] = new_circle; 
     } 

     // If not push new 
     else { 
      doc.circles.properties.push(new_circle); 
     } 

     db.foo.save(doc); 
    } 
) 

編輯

如果您不能使用saveupdateupsert選項替換if-else塊上面貼有這樣的事情應該做的伎倆:

if (i != -1) { 
    db.foo.update(
     {"_id" : doc._id, "circles.properties.name": "circle-1"}, 
     {$set: {"circles.properties.$.position": new_circle.position}} 
} 

else { 
    db.foo.update(
     {"_id" : doc._id}, 
     {$push: {"properties": new_circle }} 
    ) 
} 
+0

啊老鼠,我用的框架,Meteor,目前似乎不支持收藏存儲https://github.com/meteor/meteor/issues/584感謝我會回覆並回到這個答案。 – landland

+0

'save'只是一個shell的快捷方式,如果你檢查實現它可以很容易地被'db.foo.update({_id:doc._id},doc,true}'取代。請記住,執行任意js代碼不是非常有效的解決方案如果這是一種常見的操作,並且您關心性能,那麼修改模式可能會更好,因此您可以使用upserts – zero323

+0

Meteor I當前使用的版本不支持更新的真正標誌。是對的,這是我希望我可以避免的,但幸好這不是一種常見的操作,所以它應該就足夠了。謝謝! – landland

相關問題