2015-08-24 26 views
0

我想在這我想知道,無論是像或不像我的狀態的用戶查詢中刪除,現在我想讓它在單一的查詢,這樣我就不會調用DB 2從我的NODEJS服務器時間,有任何解決我的問題。添加和陣列中的單個查詢

對於添加我們正在使用 collection.update({_id:ID},{ $拉:{ 'USER_ID': 'XXXX-XXXX-XXXX-XXXX'}} );

對於刪除我們使用

collection.update({ _id: id }, 
    { $push: { 
     'user_id': 'xxxx-xxxx-xxxx-xxxx' } 
    } 
); 

現在,我想在一個查詢一樣,如果應用存在於水果數組中刪除它,如果不添加它使用這兩者。

+0

@JohnnyHK現在你明白我的需要? – Kashif

回答

2

的MongoDB不允許兩者$pull$push或任何其它操作,以在單個語句更新相同的「路徑」(因此單個陣列)。這主要與邏輯處理服務器端有關,更新操作從未被視爲在語句中被排序。

例子:

{ 
    "responses": [ 
     { "user": "Tom", "status": "like" }, 
     { "user": "Sarah", "status": "unlike" } 
    ] 
} 

不在於它會多大意義,但你不能做到這一點:

db.collection.update(
    {}, 
    { 
     "$pull": { "responses": { "user": "Tom", "status": "like" }, 
     "$push": { "responses": { "user": "Tom", "status": "unlike" } 
    } 
) 

由於這裏的單人操作包含「相同的路徑」兩個$push$pull作爲「迴應」。無論你如何構造聲明,都不需要以任何順序執行。

雖然我們可以「投其所好」的「湯姆」的位置,並改變了他的「身份」到「不像」代替,一個更好的模式是這樣:

{ 
    "likes": ["Tom"], 
    "unlikes": ["Sarah"], 
    "likesTotal": 1, 
    "unlikesTotal": 1, 
    "totalScore": 0 
} 

這意味着如果我想更改「湯姆」的「投票」,那麼你做一個結構就是這樣,有Bulk操作的幫助,以使單個請求和響應:

var bulk = db.collection.initializeOrderedBulkOp(); 

// Cast "Tom's" unlike where they had a "like" already 
bulk.find({ 
    "likes": "Tom", 
    "unlikes": { "$ne": "Tom" } 
}).updateOne({ 
    "$pull": { "likes": "Tom" }, 
    "$push": { "unlikes": "Tom" }, 
    "$inc": { 
     "likesTotal": -1, 
     "unlikesTotal": 1 
    } 
]); 

// Cast "Tom's" new vote where nothing was there at all 
bulk.find({ 
    "unlikes": { "$ne": "Tom" }, 
    "likes": { "$ne": "Tom" } 
}).updateOne({ 
    "$push": { "unlikes": "Tom" }, 
    "$inc": { 
     "unlikesTotal": 1, 
     "totalScore": -1 
    } 
}); 

bulk.execute(); 

這將產生一個非常好的模式。不僅每個更新操作在這裏基本上都是「原子」的,因爲通過作用於單獨的文檔屬性,每個修飾符被允許執行而不會發生衝突。而且作爲一個「批量」操作,爲滿足這裏所有可能的條件「既」更新操作的要求在單個請求被髮送,並在單個響應接收。

當然你的「客戶」的邏輯也應該知道的關於特定項目誰已經「喜歡/不喜歡的」,但一般API中執行,這是很好的做法目前的狀態。

它保持在檢查陣列,並且還保持有用計數器在檢查用於一般數據和一般查詢的目的,而不需要「計算」陣列或匹配的類型的長度。