【问题标题】:MongoDB aggregate merge two different fields as one and get countMongoDB聚合将两个不同的字段合并为一个并获取计数
【发布时间】:2015-05-15 03:49:37
【问题描述】:

我在 MongoDB 中有以下数据:

[{id:3132, home:'NSH', away:'BOS'}, {id:3112, home:'ANA', away:'CGY'}, {id:3232, home:'MIN', away:'NSH'}]

是否可以通过聚合管道获得每个团队的总游戏数?

想要的结果:

[{team: 'NSH', totalGames: 2}, {team:'MIN', totalGames: 1}, ...}]

我可以通过两个聚合调用将每个单独放在自己的数组中:

[{$group: {_id: "$home", gamesLeft: {$sum: 1}}}]

[{$group: {_id: "$away", gamesLeft: {$sum: 1}}}]

结果

var homeGames = [ { _id: 'NSH', totalGames: 1 }, { _id: 'SJS', totalGames: 2 }, ...]
var awayGames = [ { _id: 'NSH', totalGames: 1 }, { _id: 'SJS', totalGames: 4 }, ...]

但我真的想让它只处理一个查询。如果不可能,使用 javascript 将这两个结果合二为一的最佳方法是什么?

【问题讨论】:

    标签: javascript node.js mongodb mongoose


    【解决方案1】:

    经过一番困惑后,我找到了一种使用聚合管道完成它的方法。结果如下:

    db.games.aggregate([{
            $project: {
                isHome: { $literal: [true, false] },
                home: true,
                away: true
            }
        }, {
            $unwind: '$isHome'
        }, {
            $group: {
                _id: { $cond: { if: '$isHome', then: '$home', else: '$away' } },
                totalGames: { $sum: 1 }
            }
        }
    ]);
    

    如您所见,它由三个阶段组成。前两个旨在将每个文档复制成一个用于主队和一个用于客队。为此,项目阶段首先在包含 true 和 false 值的每个文档上创建一个新的 isHome 字段,然后展开阶段将其拆分为包含 true 或 false 值的单独文档。

    然后在分组阶段,我们让isHome字段决定是在home还是away字段上分组。

    如果我们可以在项目步骤中创建一个 team 字段,包含数组 [$home, $away] 会更好,但 mongo 仅支持在此处添加数组文字,因此是解决方法。

    【讨论】:

      猜你喜欢
      • 2021-12-16
      • 2021-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多