如何对 doctrine odm 中的多个字段求和?
How do I sum multiple fields in doctrine odm?
我想使用 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 的聚合生成器编写这个确切的查询?
这个比较棘手,因为文档不是很清楚。
理论上,您可以创建一个嵌套的子表达式并在其中使用求和运算符:
$builder = $this->dm->createAggregationBuilder(\Documents\BlogPost::class);
$builder->group()
->field('id')
->expression(null)
->field('games')
->sum($builder->expr()->sum('$wins', '$losses', '$ties'))
;
但是,由于聚合构建器的构建方式,它不太理解 $project
阶段之外的多个表达式的总和 syntax
,导致以下(错误)结果:
[{
"$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
阶段才应该 $sum
接受多个参数,否则默认为一个参数语法。
我会在 MongoDB ODM 中为此创建一个工单,然后看看是否可以轻松解决这个问题。
我想使用 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 的聚合生成器编写这个确切的查询?
这个比较棘手,因为文档不是很清楚。
理论上,您可以创建一个嵌套的子表达式并在其中使用求和运算符:
$builder = $this->dm->createAggregationBuilder(\Documents\BlogPost::class);
$builder->group()
->field('id')
->expression(null)
->field('games')
->sum($builder->expr()->sum('$wins', '$losses', '$ties'))
;
但是,由于聚合构建器的构建方式,它不太理解 $project
阶段之外的多个表达式的总和 syntax
,导致以下(错误)结果:
[{
"$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
阶段才应该 $sum
接受多个参数,否则默认为一个参数语法。
我会在 MongoDB ODM 中为此创建一个工单,然后看看是否可以轻松解决这个问题。