您可以只运行一个聚合流水线操作,它最初有一个流水线操作,用于对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