[英]MongoDB Aggregation combining both 'max' of EACH document and 'sum' of ALL documents
我正在记录高尔夫分数,现在正在尝试计算排行榜。 这是在 PHP 站点上使用的,所以我还需要翻译管道代码(之后)。
每个round
文档都有一个holes
数组:
{
"playerName": "Tiger Woods",
"comp": {
"name": "US Open 2021",
"courseId": "608952e3abebbd503ba6e115",
"scoringMethod": "Stableford",
"tees": "Blue",
"courseName": "MAGC Middle 9",
"roundNo": 2,
"id": {
"$oid": "607019361c071256e4f0d0d5"
}
},
"holes": [
{
"blue": 431,
"holeNett": 4,
"par": 4,
"holeGross": 5,
"no": 1,
"holeNettPoints": 2,
"yellow": 420,
"si": 2,
"holeStrokes": 1,
"white": 444,
"red": 399
},
{
"blue": 335,
"holeNett": 5,
"par": 4,
"holeGross": 5,
"no": 2,
"holeNettPoints": 1,
"yellow": 320,
"si": 8,
"holeStrokes": 0,
"white": 350,
"red": 295
},
{
"blue": 385,
"holeNett": 4,
"par": 4,
"holeGross": 5,
"no": 3,
"holeNettPoints": 2,
"yellow": 362,
"si": 4,
"holeStrokes": 1,
"white": 400,
"red": 343
},
{
"blue": 161,
"holeNett": 3,
"par": 3,
"holeGross": 3,
"no": 4,
"holeNettPoints": 2,
"yellow": 144,
"si": 7,
"holeStrokes": 0,
"white": 180,
"red": 105
},
{
"blue": 461,
"holeNett": 5,
"par": 5,
"holeGross": 6,
"no": 5,
"holeNettPoints": 2,
"yellow": 439,
"si": 1,
"holeStrokes": 1,
"white": 473,
"red": 418
},
{
"blue": 330,
"holeNett": 4,
"par": 4,
"holeGross": 4,
"no": 6,
"holeNettPoints": 2,
"yellow": 300,
"si": 9,
"holeStrokes": 0,
"white": 337,
"red": 281
},
{
"blue": 381,
"holeNett": 6,
"par": 4,
"holeGross": 6,
"no": 7,
"holeNettPoints": 0,
"yellow": 363,
"si": 5,
"holeStrokes": 0,
"white": 390,
"red": 290
},
{
"blue": 152,
"holeNett": 3,
"par": 3,
"holeGross": 3,
"no": 8,
"holeNettPoints": 2,
"yellow": 140,
"si": 6,
"holeStrokes": 0,
"white": 167,
"red": 131
},
{
"blue": 366,
"holeNett": 3,
"par": 4,
"holeGross": 4,
"no": 9,
"holeNettPoints": 3,
"yellow": 344,
"si": 3,
"holeStrokes": 1,
"white": 396,
"red": 327
}
],
"playerId": "609d0993906429612483cea0",
"holeCount": 9,
"countbackScores": [
16,
11,
5,
2
],
"team": "magc",
"date": "2021-05-20T23:00:00+00:00",
"computedScore": 16,
"computedThru": 9,
"_id": {
"$oid": "60a6aa828078924a6065dc9e"
}
}
我有一个聚合管道,可以找到每个洞的最高或最低(取决于比赛规则)分数。 我不得不$unwind
子数组,为每个播放的洞生成一个管道文件。 通常这意味着每个玩家需要 18 个文件或 9 个半轮文件。 还要注意的是,每round
都可以在不同的comp.courseId
上进行(我的初始比赛中有 3 门课程) - 所以这些课程也需要分组,因此它目前在我的$match
过滤器中。
我可以在同一管道中计算最终管道output的累计总数,同时保留以前的文件吗?
[{$match: {
"comp.id" : ObjectId('600019361c071256e4f0d0d5'),
"playerId" : "600d0993906429612483cea0",
"comp.courseId" : "600955aaabebbd503ba6e116"
}
},
{$unwind: {
path : "$holes"
}},
{$group: {
_id: "$holes.no",
hole: {
$max: "$holes"
}
}},
{$set: {
"total": { "$sum" : "$hole.holeNettPoints" }
}},
{$sort: {
"hole.no": 1
}
}]
$set
管道是我正在测试的阶段。 但这仅对来自单个文档的holeNettPoints
字段求和,因此与每个文档中的此值相同。
我不认为我可以对所有这些文档再做一个$group
,就像在我的 PHP 页面上一样,我需要其他每个孔字段来构建 HTML 表。 但它按该轮的累计总数排序。 所以我尝试使用$set
添加一个字段。 这个对吗?
这将返回每个打球的文档(我当前的数据为 9 个,通常为 18 个用于整轮高尔夫)。 我想获得所有 9 个洞的累积holeNettPoints
总数,以及每个holeNettPoints
上每个球员的每洞$max
courseId
。 一些结构:
playerId = 123456
courseId = abcdef
total = 18
holes = (
([no] => 1, [holeNettPoints] => 2),
([no] => 2, [holeNettPoints] => 2),
([no] => 3, [holeNettPoints] => 3),
([no] => 4, [holeNettPoints] => 1),
([no] => 5, [holeNettPoints] => 2),
([no] => 6, [holeNettPoints] => 2),
([no] => 7, [holeNettPoints] => 2),
([no] => 8, [holeNettPoints] => 2),
([no] => 9, [holeNettPoints] => 2),
)
理想情况下,结果将返回单个文档,然后我将能够删除playerId
$match
过滤器,以便它适用于将在每个组合中玩的许多玩家。
我希望 MongoDB 使用聚合来返回格式化和排序的结果,因此 PHP 可以循环遍历它的结果。
$group
by playerId
, courseId
和no
并获得最大的holeNettPoints
$group
by playerId
并构造no
和holeNettPoints
的holes
数组,并获得所有holeNettPoints
的总数db.collection.aggregate([
{
$match: {
"comp.id": ObjectId("607019361c071256e4f0d0d5"),
"playerId": "609d0993906429612483cea0",
"comp.courseId": "608952e3abebbd503ba6e115"
}
},
{ $unwind: { path: "$holes" } },
{
$group: {
_id: {
playerId: "$playerId",
courseId: "$comp.courseId",
no: "$holes.no"
},
holeNettPoints: { $max: "$holes.holeNettPoints" }
}
},
{
$group: {
_id: "$_id.playerId",
courseId: { $first: "$_id.courseId" },
holes: {
$push: {
no: "$_id.no",
holeNettPoints: "$holeNettPoints"
}
},
total: { $sum: "$holeNettPoints" }
}
}
])
PHP 语法:
$query = [
[
'$match' => [
'comp.id' => ObjectId("607019361c071256e4f0d0d5"),
'playerId' => "609d0993906429612483cea0",
'comp.courseId' => "608952e3abebbd503ba6e115"
]
],
[ '$unwind' => [ 'path' => '$holes' ] ],
[
'$group' => [
'_id' => [
'playerId' => '$playerId',
'courseId' => '$comp.courseId',
'no' => '$holes.no'
],
'holeNettPoints' => [ '$max' => '$holes.holeNettPoints' ]
]
],
[
'$group' => [
'_id' => '$_id.playerId',
'courseId' => [ '$first' => '$_id.courseId' ],
'holes' => [
'$push' => [
'no' => '$_id.no',
'holeNettPoints' => '$holeNettPoints'
]
],
'total' => [ '$sum' => '$holeNettPoints' ]
]
]
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.