我正在以一种简单的方式尝试平均和总结一些统计数据,但是已经碰壁了!
我有一些文档集合,其中包含以下统计信息:
{
"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添加一个条件,但不确定如何?
真的希望有人可以帮助我,并提前感谢:-)
好的,首先,你不能得到布尔值的总和,你只能得到数字的总和。所以,我假设你想在加扰值为真时加1,在这种情况下,你可以使用'$cond',它允许你写条件。
你可以尝试这样的事情,
sumScrambles: { $sum: { $cond: [ { $eq: [ "$data.holeScores.scrambled", true ] }, 1, 0 ] } }
你不一定需要$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'
}
}
}
} }
])