Javascript 在mongo中使用$sum和$cond获取$sum值,而不是实例总数
我尝试使用$group和$project操作符的组合,除非有更好的替代方法来生成两个值 考虑如下所示的文档数据结构:Javascript 在mongo中使用$sum和$cond获取$sum值,而不是实例总数,javascript,mongodb,aggregation-framework,Javascript,Mongodb,Aggregation Framework,我尝试使用$group和$project操作符的组合,除非有更好的替代方法来生成两个值 考虑如下所示的文档数据结构: [ { _id: 1, openBalance: 22, customerResponsible: true }, { _id: 2, openBalance: 16, customerResponsible: false }, { _id: 3, openBalance: 10, cus
[
{
_id: 1,
openBalance: 22,
customerResponsible: true
},
{
_id: 2,
openBalance: 16,
customerResponsible: false
},
{
_id: 3,
openBalance: 10,
customerResponsible: true
},
{
_id: 4,
openBalance: 20,
customerResponsible: false
},
]
我要做的是输出一个值为customerOpenBalance的文档,它表示customerResponsible为true的文档的总openBalance。以及一个值agencyOpenBalance,它表示customerResponsible设置为false的总openBalance
现在,我可以在$group阶段执行此操作:
然后在稍后的$project阶段执行以下操作:
"customerResponsibleOpenBalance" : { "$sum": "$customerResponsibleOpenBalance" }
但这给了我实例的$sum,而不是我实际想要的,openBalance中的$sum值,其中,对于CustomerResponsiblePenbalance,我所针对的布尔值customerResponsible是真的
如何调整此聚合以获得$openBalance中的$sum值,而不是实例的$sum值
我的完整聚合管道如下所示。关键阶段是第6阶段的$group,以及第18阶段的$project:
db.transactions.aggregate
// Pipeline
[
// Stage 1
{
$match: {
"openBalance": {
"$ne": 0.0
}
}
},
// Stage 2
{
$lookup: {
"from": "customers",
"localField": "customer.id",
"foreignField": "_id",
"as": "customer"
}
},
// Stage 3
{
$unwind: {
"path": "$customer"
}
},
// Stage 4
{
$lookup: {
"from": "visits",
"localField": "visit.id",
"foreignField": "_id",
"as": "visit"
}
},
// Stage 5
{
$unwind: {
"path": "$visit"
}
},
// Stage 6
{
$group: {
"_id": "$customer._id",
"submissions": {
"$push": "$submissions"
},
"staffMember": {
"$first": "$staffMember.id"
},
"visit": {
"$first": "$visit"
},
"openBalance": {
"$sum": "$openBalance"
},
"customerResponsibleOpenBalance": {
"$sum": {
"$cond": ["$visit.customerResponsibility", 1, 0]
}
},
"agencyResponsibleOpenBalance": {
"$sum": {
"$cond": ["$visit.customerResponsibility", 0, 1]
}
},
"openClaims": {
"$sum": {
"$cond": {
"if": {
"$gt": ["$submissions.0.responses.balance", 0.0]
},
"then": 1.0,
"else": 0.0
}
}
}
}
},
// Stage 7
{
$addFields: {
"payerInfo": "$submissions.0.details.agency._id"
}
},
// Stage 8
{
$lookup: {
"from": "agencies",
"localField": "submissions.0.details.agency._id",
"foreignField": "_id",
"as": "agency"
}
},
// Stage 9
{
$unwind: {
"path": "$agency"
}
},
// Stage 10
{
$addFields: {
"claimSupervisor": "$agency.claims.supervisor"
}
},
// Stage 11
{
$lookup: {
"from": "staffmembers",
"localField": "claimSupervisor",
"foreignField": "_id",
"as": "claimSupervisor"
}
},
// Stage 12
{
$unwind: {
"path": "$claimSupervisor"
}
},
// Stage 13
{
$lookup: {
"from": "customers",
"localField": "_id",
"foreignField": "_id",
"as": "customer"
}
},
// Stage 14
{
$unwind: {
"path": "$customer"
}
},
// Stage 15
{
$lookup: {
"from": "locales",
"localField": "customer.locale",
"foreignField": "_id",
"as": "locale"
}
},
// Stage 16
{
$unwind: {
"path": "$locale"
}
},
// Stage 17
{
$lookup: {
"from": "agencies",
"localField": "agencies",
"foreignField": "_id",
"as": "agencies"
}
},
// Stage 18
{
$project: {
"customer": {
"_id": 1.0,
"name": 1.0
},
"agency": {
"_id": 1.0,
"name": 1.0,
"transactionType": 1.0
},
"visit": {
"_id": 1.0,
"customerResponsibility": 1.0
},
"openBalance": 1.0,
"openClaims": 1.0,
"customerResponsibleOpenBalance": {
"$sum": "$customerResponsibleOpenBalance"
},
"agencyResponsibleOpenBalance": {
"$sum": "$agencyResponsibleOpenBalance"
},
"locale": {
"_id": 1.0,
"name": 1.0
},
"firstSubmission": {
"$arrayElemAt": ["$submissions", 0.0]
},
"lastSubmission": {
"$arrayElemAt": ["$submissions", -1.0]
},
"claimSupervisor": {
"_id": 1.0,
"name": 1.0
}
}
},
// Stage 19
{
$unwind: {
"path": "$firstSubmission"
}
},
// Stage 20
{
$unwind: {
"path": "$lastSubmission"
}
},
// Stage 21
{
$project: {
"firstSubmission": {
"details": 0.0,
"responses": 0.0
},
"lastSubmission": {
"details": 0.0,
"responses": 0.0
}
}
},
],
);
对不起,一开始我被你的样本数据误导了。现在,有了经过编辑的问题和完整的管道,我想你只需要从
"customerResponsibleOpenBalance" : { "$sum" : { "$cond" : [ "$customerResponsibile", 1, 0 ] }}
到
这将为customerResponsible为true时获得一个值,但我还需要customerResponsible为false时的值。我该怎么做?错了两次;请查看更新的答案,其中解释了这里发生的事情。是的。请参见此处的示例:。还可以看到我的更新答案。啊,这样你就可以把数组传递给$cond了。我没有意识到。只需交换if和else位:customerResponsibleOpenBalance:{$sum:{$cond:[$customerResponsibile:0,$openBalance]}我有一种感觉,在管道中有很多事情不太对劲。如果您可以发布一些匹配的样本数据与所需的输出,我相信我们可以得到这个权利为您。
"customerResponsibleOpenBalance" : { "$sum" : { "$cond" : [ "$customerResponsibile", 1, 0 ] }}
"customerResponsibleOpenBalance" : { "$sum" : { "$cond" : [ "$customerResponsibile", "$openBalance", 0 ] }},