【问题标题】:count documents by specific nested fields values with aggregation-framework in MongoDB在 MongoDB 中使用聚合框架按特定嵌套字段值计算文档
【发布时间】:2016-08-03 21:19:13
【问题描述】:

这是我的数据库。

{
"_id" : ObjectId("579cab6c6aba30f42a57a979"),
"iecode" : "P1111",
"country" : "India",
"totalTreatmentArms" : 3,
"treatmentArms" : [ 
    {
        "mechanismOrPkg" : "Mechanism",
        "mechanism" : "mechanism1"
    }, 
    {
        "mechanismOrPkg" : "Mechanism",
        "mechanism" : "mechanism2"
    }, 
    {
        "mechanismOrPkg" : "Package",
        "mechanism" : "mechanism1"
    }
]
}


{
"_id" : ObjectId("579cab7a6aba30f42a57a97a"),
"iecode" : "P1111",
"country" : "Canada",
"totalTreatmentArms" : 3,
"treatmentArms" : [ 
    {
        "mechanismOrPkg" : "Mechanism",
        "mechanism" : "mechanism1"
    }, 
    {
        "mechanismOrPkg" : "Mechanism",
        "mechanism" : "mechanism2"
    }, 
    {
        "mechanismOrPkg" : "Package",
        "mechanism" : ""
    }
]
}


{
"_id" : ObjectId("579cabac6aba30f42a57a97b"),
"iecode" : "P2222",
"country" : "India",
"totalTreatmentArms" : 1,
"treatmentArms" : [ 
    {
        "mechanismOrPkg" : "Package",
        "mechanism" : ""
    }
]
}


{
"_id" : ObjectId("579cabe76aba30f42a57a97c"),
"iecode" : "P3333",
"country" : "India",
"totalTreatmentArms" : 2,
"treatmentArms" : [ 
    {
        "mechanismOrPkg" : "Mechanism",
        "mechanism" : "mechanism1"
    }, 
    {
        "mechanismOrPkg" : "Package",
        "mechanism" : ""
    }
]
}

请注意,iecode : P1111 有两条记录,我希望在iecode 上区分结果,因此只考虑一条记录(任何一条)。

现在我的要求是我想依靠字段mechanismOrPkg。如果它包含值Package,那么我们将package 加一。如果值为Mechanism,那么我们将考虑字段mechanism 的值,并考虑其受尊重的值计数。

所以最终的结果会是这样的

{
"_id" : null,
"totalPackage" : 3,
"totalMechanism1" : 2,
"totalMechanism2" : 1
}

请问这听起来是否令人困惑。让我知道,即使这种聚合可以通过查询实现,或者我必须进行服务器端过滤?

谢谢。

编辑

mechanismOrPkg 的可能值:包或机制

机制的可能值:机制1或机制2

【问题讨论】:

  • 您还应该指定mechanismOrPkgMechanism 的所有文档mechanism 值是否只能有2 个值(mechanism1mechanism2),如您的示例或可能的机制数量不受您的应用程序限制,它可能是mechanism3mechanism4,...因此结果文档的长度将取决于特定的集合状态
  • @tarashypka 感谢您的关注。检查我的编辑。

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

完成上述操作需要在 $sum 累加器运算符中使用 $cond 运算符。 $cond 运算符将根据其第一个参数 (if) 计算逻辑条件,然后返回计算结果为 true (then) 的第二个参数或返回 false (else) 的第三个参数。这会将true/false 逻辑转换为分别输入$sum 的1 和0 数值。因此,例如,当您要汇总“Package”值的计数时,逻辑如下:

{
    "$sum": { 
        "$cond": [ { "$eq": [ "$treatmentArms.mechanismOrPkg", "Package" ] }, 1, 0 ]
    }
}

作为结果管道,您需要运行聚合操作

db.collection.aggregate([
    {
        "$group": {
            "_id": "$iecode",
            "treatmentArms": { "$first": "$treatmentArms" }
        }
    },
    { "$unwind": "$treatmentArms" },
    {
        "$group": {
            "_id": null,
            "totalPackage": { 
                "$sum": { 
                   "$cond": [ 
                       { "$eq": [ "$treatmentArms.mechanismOrPkg", "Package" ] }, 
                       1, 0
                    ] 
                }
            },
            "totalMechanism1":{
                "$sum": { 
                   "$cond": [ 
                        { 
                            "$and": [
                                { "$eq": [ "$treatmentArms.mechanismOrPkg", "Mechanism" ] },
                                { "$eq": [ "$treatmentArms.mechanism", "mechanism1" ] }
                            ]
                        }, 
                        1, 
                        0 ]
                }
            },
            "totalMechanism2": { 
                "$sum": { 
                   "$cond": [ 
                        { 
                            "$and": [
                                { "$eq": [ "$treatmentArms.mechanismOrPkg", "Mechanism" ] },
                                { "$eq": [ "$treatmentArms.mechanism", "mechanism2" ] }
                            ]
                        }, 
                        1, 
                        0 ]
                }
            }
        }
    }
])

样本输出

{
    "_id" : null,
    "totalPackage" : 3,
    "totalMechanism1" : 2,
    "totalMechanism2" : 1
}

【讨论】:

  • 我收到0 records fetched。我认为应该在iecode 上进行第一次分组。
  • 您是否在正确的集合上运行聚合操作?如您所见,第一个分组实际上是按iecode 字段分组。
  • 抱歉(分组)。是的,我正在查询正确的集合仍然是相同的结果。
  • 我在您提供的集合上进行了检查,并得到了预期的结果,聚合查询是正确的。它应该与您的集合有关,或者您错误地从答案中复制了查询。再次检查查询并确保您的收藏与您的问题中的完全相同。
  • @HalfBloodPrince 为您的新问题创建另一个答案,我相信有人会帮助您。评论不是为了长答案,而只是为了简短的说明。也试着在那里展示你解决问题的尝试。
猜你喜欢
  • 2014-03-04
  • 1970-01-01
  • 2020-11-13
  • 1970-01-01
  • 2020-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多