2016-01-30 54 views
0

如果這是重新發布,但是我無法完全從mongodb文檔示例中獲得我想要的查詢。插入新文檔或修改現有文檔的數組字段

這是我的問題。我無法在單個查詢中執行更新現有文檔的array_field或添加新文檔並使用初始值初始化array_field。

我可以用一些條件邏輯使用findOne(),也可能解決這個問題,但我認爲的MongoDB有這個用例

這裏的實現是迄今爲止代碼:

#data_json = JSON document to be added to collection 

collection.update_one({"json_id":data_json["json_id"], "_dashbd_id_":dashboard_id},{{"$addToSet": {"array_field":keyword}},{"$setOnInsert":data_json}}, upsert=True) 

我從我的收藏中查詢json_id和_dashbd_id_。如果它存在,那麼我打算將「關鍵字」添加到array_field。如果它不存在,創建一個新的文件作爲data_json,其中包括array_field = [關鍵字]

任何提示和建議表示讚賞!

+0

爲什麼你認爲你需要'$ setOnInsert'?你的查詢不清楚。你能否詳細說明一下? – styvane

+0

setOnInsert將文檔添加到集合中,如果它不存在(也就是說,找不到與給定的「json_id」和「_dashbd_id_」相匹配的文檔) –

回答

4

如果我正確地理解了你,你只想更新數據庫中的值,只要它們不存在以及創建帶有數組的新文檔。好的,我在這個回覆中會提到mongodb。我想你應該知道一些命令第一,這將有助於你達到同樣的效果(再有就是看一個簡單的方法)

讓我開始第一部分:

更新在一個元素陣列使用點符號索引例如:

db.collection_name.update({"_id": id}, {'$set': {"array_name.indexNumber": value}}) 

說,我們有以下的文檔中集合名稱汽車

db.cars.findOne(): 
{ 
_id: 1 
name: EvolutionX 
brand: Mitsubish 
year: 2012 
mods: [ turbo, headlights ] 
} 

說,在我們要更新上面的例子大燈rearlights我們做了以下(使用mongoshell你可以刪除鍵名引號,使用雖然數組索引時不):

db.cars.update({id:1}, {$set:{"mods.1":"rearlights"}}) 

是車頭燈的指數。

注意小心在這裏,如果你沒有使用索引數組裏面像

db.cars.update({id:1}, {$set:{"mods":"rearlights"}}) 

這將覆蓋現有文件_id:1,它會失去所有其他屬性或文件內的字段,因此它將導致以下結果:

db.cars.findOne(): 
{ 
_id: 1 
mods: [ rearlights ] 
} 

現在,假設我們想添加一個元素個輪胎MODS陣列可以使用$推爲:

db.collection_name.update({"_id": id}, {'$push': {"array_name": value}}) 

所以這將是

db.cars.update({"_id":1}, {"$push":{"mods":"tires"}}) 

現在說的,而不是更新MODS陣列要刪除「前大燈「。在這種情況下,你使用$彈出

db.cars.update({"_id":1}, {"$pop":{"mods":"headlights"}}) 

現在,記在心裏。 簡單的方法:只有在元素不存在的情況下才能將數組添加到數組中,您可以使用$ addToSet。我喜歡這個運算符,因爲如果元素不存在,它將只添加到數組中。這裏是如何使用它:

現在,如果 大燈是它不會被添加在數組中,否則將被添加到數組的末尾
db.cars.update({"_id":1}, {"$addToSet":{"mods":"headlights"}}) 

好的,這是問題的第一部分。第二部分是用數組初始化一個文檔。好的,這裏有兩個想法:第一個是你不必。使用addToSet您可以創建數組,如果它不爲存在(假設_id 2存在,但沒有MODS陣列):

db.cars.update({"_id":2}, {"$addToSet":{"mods":"bonnet"}}) 

這將創建數組,如果文檔_id: 2存在。假設_id:3不存在,您將在名爲第三屬性插頭UPSERT

db.cars.update({"_id":3}, {"$addToSet":{"mods":"headlights"}}, {upsert:true}) 

這將創建第三個文檔與陣列MODS大燈在裏頭_id: 3。但是請注意沒有其他屬性將只添加_idMODS陣列

的第二個想法是,當你插入一個新的文檔,你空MODS插入數組作爲MOD:[] 我希望幫助

+0

感謝ibininja提供的內容豐富!我想我是貪婪的,想要在一個mongo查詢中做這個動作,而不是兩個。我最終做了一個if/else語句,並確定了我的需要。感謝您的建議 –

1

假設您的data_json,dashboard_id和關鍵字包含以下詳細信息。

dashboard_id = ObjectId("5423200e6694ce357ad2a1ac") 
    keyword = "testingKeyword" 
    data_json = 
    { 
      "json_id":ObjectId("5423200e6694ce357ad2a1ac"), 
      "item":"EFG222", 
      "reorder":false, 
    } 
如果執行下面的查詢

db.collection_name.update({"json_id":data_json["json_id"], "_dashbd_id_":dashboard_id},{{"$addToSet": {"array_field":keyword}},{ upsert=True}) 

比它將推關鍵字array_field如果文件存在,或將插入新的文件有如下詳細如下

 { 
      "_id":ObjectId("5sdvsdv6sdv694ce357ad2a1ac"), 
      "json_id":ObjectId("5423200e6694ce357ad2a1ac"), 
      "dashboard_id": ObjectId("sddfb6694ce357ad2a1ac") 
      "item":"EFG222", 
      "reorder":false, 
      "array_field": 
       [      
       "testingKeyword" 
      ] 
}