首页 > 解决方案 > $unwind,除了“路径”的目标之外,还产生结果的补充

问题描述

我有一个名为 scorerecords 的 mongo 集合,其中的文档如下所示:

{status: 'in progress', teams: {count: 2, team: [ {name: "team 1", score: 100}, {name: "team 2", score: 95}]}}

我想为“teams.team”数组中的每个元素返回一个唯一记录(可以使用 $unwind 完成),但也让它返回相反的团队记录(“对手”)。例子:

{status: 'in progress', teams: {count: 2, team: {name: "team 1", score: 100}, opponent: {name: "team 2", score: 95}}}
{status: 'in progress', teams: {count: 2, team: {name: "team 2", score: 95}, opponent: {name: "team 1", score: 100}}}

这样,我将有每支球队 1 条记录(而不是每场比赛 1 条),并且可以计算球队获胜或失败的次数(例如,通过使用 $project 语句来定义“winner:true/false”字段或相似的东西)。

有什么方法可以通过一些 $aggregate 函数(如 $project/$unwind)的组合来做到这一点?

标签: mongodb

解决方案


我最终找到了解决方案:

db.scorerecords.aggregate([{$addFields: {"teams.team": {$map: {input: "$teams.team", as: "tm", in: {"name": "$$tm.name", "score":"$$tm.score", "idx": {$indexOfArray: ["$teams.team", "$$tm"]} }}}}},{$addFields: {"teams.team": {$map: {input: "$teams.team", as: "tm", in: {"name": "$$tm.name", "score": "$$tm.score", "opp": {$arrayElemAt: ["$teams.team", {$subtract: [1, "$$tm.idx"]}]}} }}}}, {$unwind: "$teams.team"} ])

似乎可能有一种更方便/有效的方法,但这种方式似乎返回了所需的结果。

步骤: 1) 使用 $map 调用添加一个标识数组中当前项的“索引”的字段。2) 使用另一个 $map 调用,添加一个“opp”字段,假设 opp 是数组中的第 (1-idx) 个条目(请参阅下面的注意事项)。3) 使用 $unwind 进行展平,创建 2 倍的原始记录集,其中包含补充记录。

第 2 步注意:(假设每个 scorerecord 将有 <=2 个团队。如果只有 1 个,则不会填充“opp”字段,这是可取的。如果超过 2 个,则会产生意外结果“teams.team”数组中的团队(例如,对于第二个之后的每个团队,它将返回数组中的最后一个元素作为“opp”)。


推荐阅读