我想使用doctrine odm的聚合构建器来构建此查询:
db.TeamStandings.aggregate(
// Pipeline
[
// Stage 1
{
$match: {
"team.$id": ObjectId("5a1643fdf5d8741a883c2aeb")
}
},
// Stage 2
{
$group: {
"_id": { "team": "team.$id" },
// This is the sum of multiple fields
"games": { $sum: { $sum: ["$wins", "$losses", "$ties"] } },
"wins": { $sum: "$wins" },
"losses": { $sum: "$losses" },
"ties": { $sum: "$ties" },
"homeWins" : { $sum: "$homeRecord.wins" },
"homeLosses" : { $sum: "$homeRecord.losses" },
"homeTies" : { $sum: "$homeRecord.ties" },
"roadWins" : { $sum: "$roadRecord.wins" },
"roadLosses" : { $sum: "$roadRecord.losses" },
"roadTies" : { $sum: "$roadRecord.ties" },
}
},
]
);
我在Studio3T中执行了此操作并获得以下内容:
{
"_id" : {
"team" : "team.$id"
},
"games" : NumberInt(776),
"wins" : NumberInt(377),
"losses" : NumberInt(398),
"ties" : NumberInt(1),
"homeWins" : NumberInt(218),
"homeLosses" : NumberInt(170),
"homeTies" : NumberInt(1),
"roadWins" : NumberInt(159),
"roadLosses" : NumberInt(228),
"roadTies" : NumberInt(0)
}
如何使用doctrine odm的聚合构建器编写这个确切的查询?
答案 0 :(得分:1)
这个很棘手,因为文档不太清楚。
理论上,您创建一个嵌套的子表达式并在那里使用sum运算符:
$builder = $this->dm->createAggregationBuilder(\Documents\BlogPost::class);
$builder->group()
->field('id')
->expression(null)
->field('games')
->sum($builder->expr()->sum('$wins', '$losses', '$ties'))
;
但是,由于构建聚合构建器的方式,它不太明白在syntax
阶段之外有多个表达式的总和$project
,导致以下(错误)结果:< / p>
[{
"$group": {
"_id": null,
"games": { "$sum": { "$sum": "$wins" } }
}
}]
要解决此问题,请在嵌套表达式中使用$add
运算符而不是$sum
:
$builder = $this->dm->createAggregationBuilder(\Documents\BlogPost::class);
$builder->group()
->field('id')
->expression(null)
->field('games')
->sum($builder->expr()->add('$wins', '$losses', '$ties'))
;
这将创建您希望它创建的聚合管道。
这很奇怪的原因是因为文档在$sum
和$group
阶段使用时定义了$project
的不同行为:在$group
中,它接受一个参数,而在$project
中它接受多个参数。但是,它在$group
内的嵌套表达式中的表现并不十分清楚:您发布的聚合管道的工作原理表明它不会将子表达式视为在$group
内阶段,因此允许多个参数。当我构建运算符时,我假设相反:只有在$project
阶段时{@ 1}}应该接受多个参数,否则默认为一个参数语法。
我将在MongoDB ODM中为此创建一张票,我会看看是否可以轻松修复。