mongodb - $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)的组合来做到这一点?
解决方案
我最终找到了解决方案:
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”)。
推荐阅读
- c# - 构建 Lambda 函数时未找到 AWS KinesisEvents 包
- reactjs - TypeScript 说空值是不可分配的,但我已经检查了可空性
- javascript - 在chartjs中设置最小值和最大值不起作用
- java - iTextPDF(版本 5)超链接未链接到正确的位置
- python - if 语句中的 .lower 函数会中断正确的输入吗?
- python - Transcypt 编译在 pathlib 中使用 python 内置属性函数失败
- ssl - URL 的哪些部分受 TLS 保护?
- php - PHP 7.2 到 PHP 7.4 升级字符串验证创建服务器性能问题
- javascript - d3 - 来自 nest() 和 sum() 的整数
- javascript - 如何使用 Axios 并获得婴儿车的响应