从嵌套对象投影平面值

时间:2018-10-20 12:58:24

标签: node.js mongodb mongoose aggregation-framework

我正在用猫鼬编写一个小型聚合,以过滤db中的值,并按它们出现的频率顺序返回它们。 例如: 假设多个文档的伙伴数组作为一个字段,这是一个对象数组,每个对象都有两个值“ partner_id”和“ passed_tests”。我想从所有文档中按其在集合中的出现频率降序归还所有唯一伙伴。

以下是示例文档:

{
    "location": "eindhoven",
    "partners": [
        {
            "partner_id": 3,
            "passed_tests": true
        },
        {
            "partner_id": 2,
            "passed_tests": false
        }
    ],
    "_id": "3136323031333066306d4438",
    "uid": "d95f2e446c052514c097e6c925408774",
    "__v": 0,
    "is_approved": true
}

我的代码如下:

function returnAll(callback) {
    TestService.aggregate([
        {
            $match: { "is_approved": true }
        },
        {
            $unwind: "$partners"
        }, {
            $group: {
                "_id": {
                    partner: { $objectToArray: "$partners" },
                    partner_id: { $arrayElemAt: ["$partner", 0] }
                },
                "count": { "$sum": 1 }
            }
        },
        {
            $sort: { "count": -1 }
        },
        {
            $project: {
                "partner_values": {
                    $map: {
                        input: "$_id.partner",
                        as: "el",
                        in: {
                            $cond: {
                                if: {
                                    $or: [{ $eq: ["$$el.v", true] },
                                    { $eq: ["$$el.v", false] }]
                                }, then: {
                                    "passed_tests": "$$el.v"
                                }, else: {
                                    "id": "$$el.v"
                                }
                            }
                        }
                    }
                },
                "count": "$count,
                "_id": 0
            }
        },
    ], function (error, data) {
        if (error) {
            logger.error(error);
            callback(null);
        } else {
            callback(data);
        }
    });
}

哪个JSON返回我的节点应用程序:

"data": [
        {
            "partner_values": [
                {
                    "id": 2
                },
                {
                    "passed_tests": false
                }
            ],
            "count": 3
        },
        {
            "partner_values": [
                {
                    "id": 6
                },
                {
                    "passed_tests": true
                }
            ],
            "count": 1
        },
        {
            "partner_values": [
                {
                    "id": 3
                },
                {
                    "passed_tests": true
                }
            ],
            "count": 1
        },
        {
            "partner_values": [
                {
                    "id": 1
                },
                {
                    "passed_tests": true
                }
            ],
            "count": 1
        }
    ]

如果我不在聚合中使用投影管道,则会得到以下提示:

"data": [
        {
            "_id": {
                "partner": [
                    {
                        "k": "partner_id",
                        "v": 2
                    },
                    {
                        "k": "passed_tests",
                        "v": false
                    }
                ],
                "partner_id": null
            },
            "count": 3
        },
        {
            "_id": {
                "partner": [
                    {
                        "k": "partner_id",
                        "v": 6
                    },
                    {
                        "k": "passed_tests",
                        "v": true
                    }
                ],
                "partner_id": null
            },
            "count": 1
        },
        {
            "_id": {
                "partner": [
                    {
                        "k": "partner_id",
                        "v": 3
                    },
                    {
                        "k": "passed_tests",
                        "v": true
                    }
                ],
                "partner_id": null
            },
            "count": 1
        },
        {
            "_id": {
                "partner": [
                    {
                        "k": "partner_id",
                        "v": 1
                    },
                    {
                        "k": "passed_tests",
                        "v": true
                    }
                ],
                "partner_id": null
            },
            "count": 1
        }
    ]

这很容易理解,因为我正在引入“ _id”和其他额外的字段来查询数组并找到值。但是,我想要的输出是:

"data": {
            "partners": [{
                "id": 2,
                "passed_tests": false,
                "count": 3
            }, {
                "id": 6,
                "passed_tests": false,
                "count": 1
            }, {
                "id": 3,
                "passed_tests": false,
                "count": 1
            }, {
                "id": 1,
                "passed_tests": false,
                "count": 1
            }]
        }

我可以在这方面得到一些帮助吗?谢谢。

1 个答案:

答案 0 :(得分:1)

您可以使用以下汇总查询。

TestService.aggregate([
  {"$match":{"is_approved":true}},
  {"$unwind":"$partners"},
  {"$group":{
    "_id":{"partner_id":"$partners.partner_id","passed_tests":"$partners.passed_tests"},
    "count":{"$sum":1}
  }},
  {"$sort":{"count":-1}},
  {"$group":{
    "_id":null,
    "partners":{"$push":{"id":"$_id.partner_id","passed_tests":"$_id.passed_tests","count":"$count"}}
  }},
  {"$project":{"partners":1}}
])