2012-11-27 151 views
3

我有一點mongo問題。我想知道是否有辦法在mongo控制檯命令中執行以下操作,而不是多個findupdate調用。基於id更新數組對象?

{ 
    "_id" : ObjectId("50b429ba0e27b508d854483e"), 
    "array" : [ 
     { 
      "id" : "1", 
      "letter" : "a" 
     }, 
     { 
      "id" : "2", 
      "letter" : "b" 
     } 
    ], 
    "tester" : "tom" 
} 

我想用這個新的數組項

{ 
    "id": "2", 
    "letter": "c" 
} 

我用這個更新的對象,addToSet是有限的,它不會插入一項的數組,如果它已經存在,但它將不會基於標識符更新項目。在這種情況下,我真的很想根據id更新此條目。

db.soup.update({ 
    "tester": "tom" 
}, { 
    $addToSet: { 
     "array": { 
      "id": "2", 
      "letter": "c" 
     } 
    } 
}); 

這給了我:

{ 
    "_id" : ObjectId("50b429ba0e27b508d854483e"), 
    "array" : [ 
     { 
      "id" : "1", 
      "letter" : "a" 
     }, 
     { 
      "id" : "2", 
      "letter" : "b" 
     }, 
     { 
      "id" : "2", 
      "letter" : "c" 
     } 
    ], 
    "tester" : "tom" 
} 

當我真正想要的是:

{ 
    "_id" : ObjectId("50b429ba0e27b508d854483e"), 
    "array" : [ 
     { 
      "id" : "1", 
      "letter" : "a" 
     }, 
     { 
      "id" : "2", 
      "letter" : "c" 
     } 
    ], 
    "tester" : "tom" 
} 

回答

6

可以使用$位置操作做到這一點:

db.soup.update(
    {_id: ObjectId("50b429ba0e27b508d854483e"), 'array.id': '2'}, 
    {$set: {'array.$.letter': 'c'}}) 

更新對象中的充當array的第一個元素的佔位符以匹配查詢選擇器。

+0

這是一個很好的一個。我今晚學到了一些東西。 – ddoxey

+0

這太好了。我只是意識到這就是我所擁有的。現在更復雜的問題是,我怎樣才能以某種方式將新對象例如'{「id」:3,「letter」:「d」}'推到數組中?我是否必須以編程方式將請求排序?如果它存在,如果不是'$ push',使用'$ set'? – ThomasReggi

+0

@ThomasReggi如果你作爲一個單獨的問題提出這個問題會更好。 – JohnnyHK

0

在這裏你去:

> db.collection.insert({ array : [ { id : 1, letter : 'a' }, { id : 2, letter : 'b' } ], tester : 'tom' }); 
> db.collection.findOne(); 
{ 
    "_id" : ObjectId("50b431a69a0358d590a2f5f0"), 
    "array" : [ 
     { 
      "id" : 1, 
      "letter" : "a" 
     }, 
     { 
      "id" : 2, 
      "letter" : "b" 
     } 
    ], 
    "tester" : "tom" 
} 
> db.collection.update({ tester : 'tom' }, { $set : { 'array.1' : { id : 2, letter : 'c' } } }, false, true); 
> db.collection.findOne(); 
{ 
    "_id" : ObjectId("50b431a69a0358d590a2f5f0"), 
    "array" : [ 
     { 
      "id" : 1, 
      "letter" : "a" 
     }, 
     { 
      "id" : 2, 
      "letter" : "c" 
     } 
    ], 
    "tester" : "tom" 
} 

訣竅在於假的,真的,假的。 即:對於upsert爲true,對於更新倍數爲false。

欲瞭解更多詳情請查看: http://www.mongodb.org/display/DOCS/Updating#Updating-update%28%29

+0

你正在更新基於數組的位置('array.1 ')而不是找到'id'是'2'的條目。這隻適用於已經知道數組中元素的位置,而不僅僅是'id'的情況。 – Stennie

+0

這個問題暗示了標準是{tester:'tom'}並且他想要替換'array'列表的第二個元素。如果標準還必須包含{'array.id':2},那麼JohnnyHK的解決方案看起來就像這裏的贏家。 – ddoxey