MongoDB在聚合组中计数为真

问题描述 投票:0回答:2

我正在以一种简单的方式尝试平均和总结一些统计数据,但是已经碰壁了!

我有一些文档集合,其中包含以下统计信息:

{
  "playerId": "5c6024b5031f5bc44d790e01",
  "courseId": "5b2a0ab1c6dc0f04e9a1e769",
  "gir": true,
  "data": {
    "roundHoles": [
      {
        "type": "HoleData",
        "holeNo": 1,
        "par": 3,
        "hcp": 18
      },
      {
        "type": "HoleData",
        "holeNo": 2,
        "par": 4,
        "hcp": 4
      },
      {
        "type": "HoleData",
        "holeNo": 3,
        "par": 4,
        "hcp": 8
      }
    ],
    "holeScores": [
      {
        "type": "RoundHoleData",
        "strokes": 3,
        "points": 2,
        "puts": 1,
        "gir": true,
        "scrambled": false
      },
      {
        "type": "RoundHoleData",
        "strokes": 5,
        "points": 1,
        "puts": 2,
        "gir": false,
        "scrambled": false
      },
      {
        "type": "RoundHoleData",
        "strokes": 4,
        "points": 2,
        "puts": 1,
        "gir": false,
        "scrambled": true
      }
    }
  }
}

我想要做的是获得平均笔画,分数和看跌期权以及加权和gir的总和,只有当主“gir”设置为true时才会生成。

这是我到目前为止所提出的:

var allScores = runtimeCollection('roundScores').aggregate(
  {
      $match: { "playerId": playerId, "courseId": "5b2a0ab1c6dc0f04e9a1e769" }
  },
  {
      $unwind: {
          path: "$data.holeScores",
          includeArrayIndex: "index"
      }
  },
  {
      $group: {
          _id: "$index",
          rounds: { $sum: 1 },
          avgStrokes: { $avg: "$data.holeScores.strokes" },
          avgPoints: { $avg: "$data.holeScores.points" },
          avgPuts: { $avg: "$data.holeScores.puts" },
          sumScrambles: { $sum: "$data.holeScores.scrambled" }
      }
  }
);

以下是我从中得到的结果:

{
  "_id": 17,
  "rounds": 18,
  "avgStrokes": 3.4444444444444446,
  "avgPoints": 1.2777777777777777,
  "avgPuts": 1.6111111111111112,
  "sumScrambles": 0
},
{
  "_id": 14,
  "rounds": 18,
  "avgStrokes": 5.388888888888889,
  "avgPoints": 2.1666666666666665,
  "avgPuts": 1.5,
  "sumScrambles": 0
},
{
  "_id": 12,
  "rounds": 18,
  "avgStrokes": 5,
  "avgPoints": 1.6111111111111112,
  "avgPuts": 1.8333333333333333,
  "sumScrambles": 0
}

看起来我得到的平均部件很好,但总和不起作用。我想我必须为sumScrambles添加一个条件,但不确定如何?

真的希望有人可以帮助我,并提前感谢:-)

mongodb grouping aggregate condition
2个回答
1
投票

好的,首先,你不能得到布尔值的总和,你只能得到数字的总和。所以,我假设你想在加扰值为真时加1,在这种情况下,你可以使用'$cond',它允许你写条件。

你可以尝试这样的事情,

sumScrambles: { $sum: { $cond: [ { $eq: [ "$data.holeScores.scrambled", true ] }, 1, 0 ] } }

1
投票

你不一定需要$unwind$group来获得这个聚合的平均值和总和,所有这些都可以在$project阶段完成,因为$sum$avg运算符也在$project阶段工作,因为字段是数组。

至于条件和,你可以在数组上使用$filter,然后用$size计算简化数组中的元素,得到一个总和。

以下管道演示了这种方法

runtimeCollection('roundScores').aggregate([
    { '$match': { 'playerId': playerId, 'courseId': '5b2a0ab1c6dc0f04e9a1e769' } },
    { '$project': {
        'rounds': { '$size': '$data.holeScores' },
        'avgStrokes': { '$avg': '$data.holeScores.strokes' },
        'avgPoints': { '$avg': '$data.holeScores.points' },
        'avgPuts': { '$avg': '$data.holeScores.puts' },
        'avgPars': { '$avg': '$data.roundHoles.par' },
        'sumScrambles': { 
            '$size': {
                '$filter': {
                    'input': '$data.holeScores',
                    'cond': '$$this.scrambled'
                }
            }
        }
    } }
])
© www.soinside.com 2019 - 2024. All rights reserved.