2012-04-23 110 views
11

目前,我有以下數據集:「UPSERT」

{ 
    'component_id':1, 
    '_locales':[ 
     { 
      'url': 'dutch', 
      'locale': 'nl_NL' 
     } 
    ] (etc) 
} 

如果我想更新的語言環境我可以運行類似的東西行:

db.components.update(
    {'component_id': 1, '_locales.locale': 'nl_NL'}, 
    {$set: {'_locales.$': {'url': 'new url','locale':'nl_NL'}}, 
    true 
); 

該作品直到現場不存在:

db.components.update(
    {'component_id': 1, '_locales.locale': 'en_US'}, 
    {$set: {'_locales.$': {'url': 'new url','locale':'en_US'}}, 
    true 
); 

因爲在component_id上有一個唯一的索引,所以會拋出一個excep抱怨一個重複的密鑰。

有沒有辦法自動添加新的「文檔」與不同的語言環境,並更新它,如果它已經存在?根據使用位置運算符的文檔不能用'插入'。

回答

10

您可以使用$addToSet添加到一個確保沒有重複的數組元素,但這不適用於您的「更新」的情況。

爲了做到你想要什麼,你需要將你的數據結構更改爲類似:

{ 
    "_id" : ObjectId("4f9519d6684c8b1c9e72e367"), 
    "component_id" : 1, 
    "_locales" : { 
     "nl_NL" : { 
      "url" : "dutch" 
     } 
    } 
} 

現在你可以在nl_NL區域做一個更新只:

db.components.update({ component_id: 1 }, { $set: { '_locales.nl_NL.url' : 'new url' } }, true); 

和新的語言環境也能發揮作用,比如有:

db.components.update({ component_id: 1 }, { $set: { '_locales.en_US.url' : 'American' } }, true); 

您可能要consid呃到具有語言環境嵌套對象的一部分,以及也許,像:

{ 
    "_id" : ObjectId("4f9519d6684c8b1c9e72e367"), 
    "component_id" : 1, 
    "_locales" : { 
     "nl_NL" : { 
      "url" : "dutch" 
      "locale" : "nl_NL"     
     } 
    } 
} 

這使得它更容易找回在某些情況下的數據。

+1

嗨德里克,謝謝你的回覆。你的建議實際上是我最初的數據結構,我改變了上述。一個原因是創建索引:_locales.url而不是在每個區域設置: _locales.nl_NL.url,_locales.en_US.url等 目前我通過獲取所有_locales數據並修改/添加區域設置I '正在'手動'工作。當我完成後,我用新的替換當前的'_locales'。現在這樣就足夠了,表現明智這可能不是一個好主意。 – 2012-04-23 09:32:43

+0

我也同意,由於索引的原因,使用「未定義」鍵通常不是一件好事。有時,如果由於其他情況下的索引/其他原因而提高性能,則最好是執行兩次查詢來執行更新。大部分時間沒有真正的「正確方式」。玩它,如果它不執行更改它並運行兩個查詢更新。 – Derick 2012-04-23 12:35:35

+0

@Derick:我正面臨類似的問題。 http://stackoverflow.com/questions/32038606/defining-a-map-with-objectid-key-and-array-of-strings-as-value-in-mongoose-schem – 2015-08-17 10:45:29