因爲你有嵌套數組,所以直到添加來自SERVER-831的功能請求才能作爲單個查詢進行。一旦嵌套$elemMatch
運營商被允許,那麼你的更新將如下所示。 注:本目前不工作,語法甚至尚未定義 - 它是僅用於說明目的:
db.foo.update(
{modules: {$elemMatch: { systems: {$elemMatch: {systemId : 13}}}}},
{ $set : {"modules.$0.systems.$1" : {d : null}}}
);
這一發現一塊查詢的工作當前,但更新件作品將不允許即使您從理論上的$0
和$1
恢復到當前的$
,也會出現多個位置運算符。
即使那麼你會碰到$ elemMatch上的第一個元素匹配限制(它不匹配多個/所有元素,只是它找到的第一個元素),因此你可能不得不多次運行這個來更新所有文檔,至少要到SERVER-1243完成。
爲了說明如何做到這一點與單個陣列的工作是非常簡單的,讓我們將您的樣品文檔拖放模塊領域:
db.bar.insert([{
systems:[
{ systemId: 13, count: 2 },
{ systemId: 20, count: 7 },
{ systemId: 8, count: 1 }
]
},
{
systems:[
{ systemId: 13, count: 2 },
{ systemId: 20, count: 7 }
]
}
]);
這基本上是創建兩個文件(它把每個元素的數組中要插入的文檔)。所以,我們有2個文檔現在:
> db.bar.find()
{ "_id" : ObjectId("5450e0708e1b8924251e1330"), "systems" : [ { "systemId" : 13, "count" : 2 }, { "systemId" : 20, "count" : 7 }, { "systemId" : 8, "count" : 1 } ] }
{ "_id" : ObjectId("5450e0708e1b8924251e1331"), "systems" : [ { "systemId" : 13, "count" : 2 }, { "systemId" : 20, "count" : 7 } ] }
要更新這些文檔所概述(只要有只爲systemId : 13
一場比賽,你就可以做到以下幾點:
>db.bar.update(
{ systems: {$elemMatch: {systemId : 13}}},
{ $set : {"systems.$" : {d : null}}},
{multi : true}
);
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })
讓我們來看看在我們的文檔中再次提到:
> db.bar.find()
{ "_id" : ObjectId("5450e1198e1b8924251e1332"), "systems" : [ { "d" : null }, { "systemId" : 20, "count" : 7 }, { "systemId" : 8, "count" : 1 } ] }
{ "_id" : ObjectId("5450e1198e1b8924251e1333"), "systems" : [ { "d" : null }, { "systemId" : 20, "count" : 7 } ] }
您是否可以將您的數據轉換爲這種格式,即使是暫時的?是的,但它意味着一個新的集合:
db.foo.aggregate([
{$match: {modules: {$elemMatch: { "systems": {$elemMatch: {"systemId" : 13}}}}}},
{$unwind : "$modules"},
{$project : {"_id" : 0, "systems" : "$modules.systems"}},
{$out : "flattened_systems"}
])
// confirm the new doc structure
db.flattened_systems.find()
{ "_id" : ObjectId("5450e4702127b5e51e8a9e0a"), "systems" : [ { "systemId" : 13, "count" : 2 }, { "systemId" : 20, "count" : 7 }, { "systemId" : 8, "count" : 1 } ] }
{ "_id" : ObjectId("5450e4702127b5e51e8a9e0b"), "systems" : [ { "systemId" : 13, "count" : 2 }, { "systemId" : 20, "count" : 7 } ] }
然後,您可以運行上面的更新修改systemIds
和重新聚集找回原來的結構:
db.flattened_systems.update(
{ systems: {$elemMatch: {systemId : 13}}},
{ $set : {"systems.$" : {d : null}}},
{multi : true}
);
db.flattened_systems.aggregate([
{$group : { "_id" : 0, "modules" : {$push : {"systems" : "$systems"}}}},
{$project : {"_id" : 0, "modules" : 1, "flag" : {$literal : "new"}}},
{$out : "processed_systems"}
])
因此, processed_systems
現藏有你想要的格式(DOC額外的「新」的標誌是可選的,以顯示你怎麼可能標誌作爲更新):
> db.processed_systems.find()
{ "_id" : ObjectId("5450e9e92127b5e51e8a9e10"), "modules" : [ { "systems" : [ { "d" : null }, { "systemId" : 20, "count" : 7 }, { "systemId" : 8, "count" : 1 } ] }, { "systems" : [ { "d" : null }, { "systemId" : 20, "count" : 7 } ] } ], "flag" : "new" }
不理想,particu如果正在積極更新文檔(無法自動完成此操作),但希望它能讓您瞭解如何在此期間進行此操作。我敢肯定,你也可以使用Map Reduce來做到這一點,但將它作爲一個單獨的問題可能會更好。