您可以只運行一個聚合流水線操作,它最初有一個流水線操作,用於對Payment
集合執行「左連接」。爲了從作爲一個名爲payments
的數組嵌入結果文檔中的正確集合(付款)中獲取數據,這是必需的。
前述$unwind
管道解構嵌入式payments
陣列即,它會爲每一個payments
數據字段的每一個元素的新記錄和。它基本上平整了將在下一個階段有用的數據。
在此$group
流水線階段,您可以通過應用累加器表達式來計算所需的聚合。如果比如你Person
架構中有您希望保留其他領域,那麼$first
蓄電池經營者應在除了足夠的$max
運營商的額外maxPay
領域。
UPDATE
不幸的是,沒有運營商 「包括所有字段」 在$group
聚集流水線操作。這是因爲流水線步驟主要用於對來自收集字段(sum,avg等)的數據進行分組和計算/彙總,並且返回所有集合的字段不是流水線的預期用途。組管道運算符類似於SQL的GROUP BY
子句,除非使用任何聚合函數(MongoDB中的累加器運算符),否則不能使用GROUP BY
。同樣,如果你需要保留大部分字段,你也必須在MongoDB中使用聚合函數。在這種情況下,您必須將$first
應用於您要保留的每個字段。
您還可以使用引用根文檔的系統變量$$ROOT
。請將本文件的所有字段的字段中$group
管道內,例如:
{
"$group": {
"_id": "$_id",
"maxPay": { "$max": "$payments.amount" },
"doc": { "$first": "$$ROOT" }
}
}
這種方法的缺點是,你需要進一步$project
管道,使它們符合重塑場原始模式,因爲生成的管道中的文檔只有三個字段; _id
,maxPay
和嵌入式doc
字段。
最後的流水線階段,$out
,寫入產生的聚合管道輸送到同一個集合的文件,類似於用新的結果集合原子取代現有的收集更新Person
集合。 $out
操作不會更改以前集合中存在的任何索引。如果匯聚失敗,則$out
操作不更改的現有集合:
db.Person.aggregate([
{
"$lookup": {
"from": "Payment",
"localField": "_id",
"foreignField": "playerId",
"as": "payments"
}
},
{ "$unwind": {
"path": "$payments",
"preserveNullAndEmptyArrays": true
} },
{
"$group": {
"_id": "$_id",
"maxPay": { "$max": "$payments.amount" },
/* extra fields for demo purposes
"firstName": { "$first": "$firstName" },
"lastName": { "$first": "$lastName" }
*/
}
},
{ "$out": "Person" }
])
你做錯了。向我們展示樣本文件的收集和預期結果。另外考慮添加你的MongoDB服務器版本。 – styvane
'個人:{_id},付款方式:{personId,金額}'。預期的人有場maxPay。使用mongodb 3.2 – awfun