2014-12-13 26 views
0

我有一個集合:MongoDB的更新/陣列的Upsert準確匹配

​​

我希望能夠以更新的標準定數組的數組的統計信息的文件(精確匹配)。

我嘗試這樣做2個階段:

db.gStats.update({ 
    "criteria" : {$size : 2}, 
    "criteria" : {$all : [{"key1" : "2096955"},{"value1" : "2015610"}]} 
}, 
{ 
    $pull : {groups : {"id" : "XXXX"}} 
} 
) 

推新文件

db.gStats.findAndModify({ 
    query : { 
     "criteria" : {$size : 2}, 
     "criteria" : {$all : [{"key1" : "2015610"}, {"key2" : "2096955"}]} 
    }, 
    update : { 
     $push : {groups : {"id" : "XXXX", "visited" : 29, "liked" : 144}} 
    }, 
    upsert : true 
}) 

的:

從給定的 「ID」 的陣列拉統計文件拉查詢完美。

2014-12-13T15:12:58.571+0100 findAndModifyFailed failed: { 
     "value" : null, 
     "errmsg" : "exception: Cannot create base during insert of update. Cause 
d by :ConflictingUpdateOperators Cannot update 'criteria' and 'criteria' at the 
same time", 
     "code" : 12, 
     "ok" : 0 
} at src/mongo/shell/collection.js:614 

回答

1

無論查詢是在現實工作: 推式查詢提供了一個錯誤。除非在運營商和$and之下,您不能使用像「標準」這樣的密鑰名稱。您還指定不同的字段(即組)和查詢樣本文檔中不存在的元素。

很難說出你真正想在這裏做什麼。但是這個錯誤主要是由我提到的第一個問題引起的,另外還有一些額外的東西。所以真的你的{ "$size": 2 }條件被忽略,只有第​​二個條件適用。

有效查詢形式應該是這樣的:

query: { 
    "$and": [ 
     { "criteria" : { "$size" : 2 } }, 
     { "criteria" : { "$all": [{ "key1": "2015610" }, { "key2": "2096955" }] } } 
    ] 
} 

作爲每組條件由$and查詢的文檔結構是有效的,不具有散列鍵名提供的陣列內指定的覆蓋另一個。這是編寫你的兩個條件的正確方法,但是有一個技巧使得「upsert」由於那些條件與文檔不匹配而失敗。我們需要重寫發生了什麼事時,它嘗試應用上創建$all參數:

update: { 
    "$setOnInsert": { 
     "criteria" : [{ "key1": "2015610" }, { "key2": "2096955" }] 
    }, 
    "$push": { "stats": { "id": "XXXX", "visited": 29, "liked": 144 } } 
} 

使用$setOnInsert這樣,當「更新插入」被應用在這裏所規定的條件,而不是使用一個新的文檔創建替代地使用在語句的查詢部分中設置的字段值。

當然,如果你真正需要的是真正的數組中的內容的精確匹配,那麼只需要使用的查詢,而不是:

query: { 
    "criteria" : [{ "key1": "2015610" }, { "key2": "2096955" }] 
} 

然後MongoDB的會很樂意在創建新文檔時應用這些值,並且不會對如何解釋$all表達式感到困惑。

+1

請注意,對於'criteria'上的兩個條件,您不需要'$和'。條件可以按照「條件」來構造:{「$ size」:2,「$ all」:[{「key1」:「2015610」},{「key2」:「2096955」}]}' – wdberkeley 2014-12-15 17:25:20