Mongodb 使用与条件和分组匹配的子文档计数进行聚合

Mongodb 使用与条件和分组匹配的子文档计数进行聚合,mongodb,mongoose,mongodb-query,aggregation-framework,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,我收集了如下文件: { "_id" : ObjectId("55d4410544c96d6f6578f893"), "executionProject" : "Project1", "suiteList" : [ { "suiteStatus" : "PASS" } ], "runEndTime" : ISODate("2015-08-19T08:40:47.049Z"), "runStar

我收集了如下文件:

{
    "_id" : ObjectId("55d4410544c96d6f6578f893"),
    "executionProject" : "Project1",
    "suiteList" : [ 
        {
            "suiteStatus" : "PASS"
        }
    ],
    "runEndTime" : ISODate("2015-08-19T08:40:47.049Z"),
    "runStartTime" : ISODate("2015-08-19T08:40:37.621Z"),
    "runStatus" : "PASS",
    "__v" : 1
}

{
    "_id" : ObjectId("55d44eb4c0422e7b8bffe76b"),
    "executionProject" : "Project1",
    "suiteList" : [ 
        {
            "suiteStatus" : "PASS"
        }
    ],
    "runEndTime" : ISODate("2015-08-19T09:39:13.528Z"),
    "runStartTime" : ISODate("2015-08-19T09:39:00.406Z"),
    "runStatus" : "PASS",
    "__v" : 1
}

{
    "_id" : ObjectId("55d44f0bc0422e7b8bffe76f"),
    "executionProject" : "Project1",
    "suiteList" : [ 
        {
            "suiteStatus" : "FAIL"
        }
    ],
    "runEndTime" : ISODate("2015-08-19T09:46:31.108Z"),
    "runStartTime" : ISODate("2015-08-19T09:40:27.377Z"),
    "runStatus" : "PASS",
    "__v" : 1
}

{
    "_id" : ObjectId("55d463d0c0422e7b8bffe789"),
    "executionProject" : "Project2",
    "suiteList" : [ 
        {
            "suiteStatus" : "PASS"
        },
        {
            "suiteStatus" : "PASS"
        }
    ],
    "runEndTime" : ISODate("2015-08-19T11:09:52.537Z"),
    "runStartTime" : ISODate("2015-08-19T11:09:04.539Z"),
    "runStatus" : "FAIL",
    "__v" : 1
}

{
    "_id" : ObjectId("55d464ebc0422e7b8bffe7c2"),
    "executionProject" : "Project3",
    "suiteList" : [ 
        {
            "suiteStatus" : "FAIL"
        }
    ],
    "runEndTime" : ISODate("2015-08-19T11:18:41.460Z"),
    "runStartTime" : ISODate("2015-08-19T11:13:47.268Z"),
    "runStatus" : "FAIL",
    "__v" : 10
} 
我希望输出如下:

[
    {
        "executionProject": "Project1",
        "suite-pass": 0,
        "suite-fail": 1,
        "runEndTime": ISODate("2015-08-19T09:46:31.108Z")
    },
    {
        "executionProject": "Project2",
        "suite-pass": 2,
        "suite-fail": 0,
        "runEndTime": ISODate("2015-08-19T11:09:52.537Z")
    },
    {
        "executionProject": "Project3",
        "suite-pass": 0,
        "suite-fail": 1,
        "runEndTime": ISODate("2015-08-19T11:18:41.460Z")
    },
]
我想按项目分组,按运行时排序,并显示suiteList的通过和失败计数

我尝试了Blakes在中提出的建议:


我希望
Project2的
suite pass
计数为2,因为suiteList中有2个元素,但它返回1。

展开
suiteList
,并在
组中使用
$sum
,如下所示:

db.testruns.aggregate({
    "$unwind": "$suiteList"
}, {
    "$group": {
        "_id": "$executionProject",
        "suite-pass": {
            "$sum": {
                "$cond": {
                    "if": {
                        "$eq": ["$suiteList.suiteStatus", "PASS"]
                    },
                    "then": 1,
                    "else": 0
                }
            }
        },
        "suite-fail": {
            "$sum": {
                "$cond": {
                    "if": {
                        "$eq": ["$suiteList.suiteStatus", "FAIL"]
                    },
                    "then": 1,
                    "else": 0
                }
            }
        },
        "runEndTime": {
            "$last": "$runEndTime"
        }
    }
}, {
    "$sort": {
        "runEndTime": 1
    }
})

您应该已经正确地阅读了答案,因为已经有了另一个替代列表,并解释了为什么您希望得到与您使用的结果不同的预期结果

相反,您想要的是这一个,它尊重可能的多个“通过”或“失败”:

Model.aggregate(
[
{“$sort”:{“executionProject”:1,“runEndTime”:1},
{“$组”:{
“\u id”:“$executionProject”,
“suiteList”:{“$last”:“$suiteList”},
“runEndTime”:{“$last”:“$runEndTime”}
}},
{“$unwind”:“$suiteList”},
{“$组”:{
“\u id”:“$\u id”,
“套房通行证”:{
“$sum”:{
“$cond”:[
{“$eq”:[“$suiteList.suiteStatus”,“PASS”]},
1.
0
]
}
},
“套件失败”:{
“$sum”:{
“$cond”:[
{“$eq”:[“$suiteList.suiteStatus”,“FAIL”]},
1.
0
]
}
},
“runEndTime”:{“$first”:“$runEndTime”}
}},
{“$sort”:{“runEndTime”:1}
],
函数(错误、结果){
}
);
这是一种方法的“组合”。第一个是在运行时获得您所期望的“last”。下一步是分解数组,这一次实际“汇总”通过或失败的可能发生次数,而不是仅记录数组中通过或失败的
1
,而是计算实际的“通过”或“失败”

结果如下:

{
“_id”:“项目1”,
“套房通行证”:0,
“套件失败”:1,
“运行时间”:ISODate(“2015-08-19T09:46:31.108Z”)
}
{
“_id”:“项目2”,
“套房通行证”:2,
“套件失败”:0,
“运行时间”:ISODate(“2015-08-19T11:09:52.537Z”)
}
{
“_id”:“项目3”,
“套房通行证”:0,
“套件失败”:1,
“运行时间”:ISODate(“2015-08-19T11:18:41.460Z”)
}

这将
Project1
的套件通过计数返回为2,套件失败计数返回为1。我希望套件通过计数为0,套件失败计数为1。@Vimal您知道这是我最初给您的答案的直接复制粘贴,之前您明确表示您想要的是“最后一个”而不是“总和”。让你知道你的回报是什么。你是一个天才。如果你在这附近,我想请你喝杯啤酒。
db.testruns.aggregate({
    "$unwind": "$suiteList"
}, {
    "$group": {
        "_id": "$executionProject",
        "suite-pass": {
            "$sum": {
                "$cond": {
                    "if": {
                        "$eq": ["$suiteList.suiteStatus", "PASS"]
                    },
                    "then": 1,
                    "else": 0
                }
            }
        },
        "suite-fail": {
            "$sum": {
                "$cond": {
                    "if": {
                        "$eq": ["$suiteList.suiteStatus", "FAIL"]
                    },
                    "then": 1,
                    "else": 0
                }
            }
        },
        "runEndTime": {
            "$last": "$runEndTime"
        }
    }
}, {
    "$sort": {
        "runEndTime": 1
    }
})