我正在尋找一個 MongoDB 聚合管道,它使用條件陳述句更新陣列。我的資料如下所示:
{
"_id": 1,
"locations": [
{
"controllerID": 1,
"timestamp": 1234
},
{
"controllerID": 2,
"timestamp": 2342
}
]
},...
潛在的新條目:
{
"controllerID": 2,
"timestamp": //will be set automatically
}
首先,我想匹配 _id (不是問題),然后如果具有最新/最新時間戳的元素具有不同的控制器 ID,則將新條目推送到位置陣列。推送新的位置物件時,將自動設定時間戳。
示例 1
輸入:
{
"controllerID": 2,
}
預期結果:
{
"_id": 1,
"locations": [
{
"controllerID": 1,
"timestamp": 1234
},
{
"controllerID": 2,
"timestamp": 2342
}//noting is added because the newset entry in the array has the same controllerID
]
},
示例 2
輸入:
{
"controllerID": 1,
}
預期結果:
{
"_id": 1,
"locations": [
{
"controllerID": 1,
"timestamp": 1234
},
{
"controllerID": 2,
"timestamp": 2342
},
{//added because the controllerID is different to te last element
"controllerID": 1,
"timestamp": 4356
}
]
},
提前致謝!
uj5u.com熱心網友回復:
這是一個解決方案。
var candidate = 2;
rc=db.foo.update({}, // add matching criteria here; for now, match ALL
[
[
// We cannot say "if condition then set fld = X else do nothing".
// We must say "set fld to something based on condition."
// The common pattern becomes:
// "Set fld to (if condition then X else fld)"
// in other words, set the fld to *itself*
//
// Note the use of the dot operator on the $locations field.
// Also, not sure about what sort of new timestamp is desired so let's
// just throw in an ISODate() for now.
{$set: {'locations': {$cond: [
{$ne:[candidate, {$last:'$locations.controllerID'}]}, // IF not same as candidate...
{$concatArrays: ['$locations',
// $concatArrays wants arrays, not objects, so we must wrap our new
// object with [] to make an array of 1:
[ {controllerId:candidate,timestamp:new ISODate() } ]
]}, // THEN concat a new entry to end of existing locations
'$locations' // ELSE just set back to existing locations
]}
}}
],
{multi:true}
);
該引擎“足夠聰明”,可以意識到將欄位設定為自身不會觸發修改,因此該方法是高效的,并且不會重寫整個匹配物件集;這可以在update()呼叫的輸出中看到,例如:
printjson(rc);
{ "nMatched" : 1002, "nUpserted" : 0, "nModified" : 1 }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/453622.html
下一篇:如何查詢嵌套陣列mongodb
