MongoDB $ lookup结果作为对象而不是数组

时间:2018-12-23 07:14:46

标签: node.js mongodb mongodb-query aggregation-framework

表“用户”:

{
    "_id" : ObjectId("573b09e6322304d5e7c6256e"),
    "name" : "John",
    "age" : 30,
    "list" : [ 
        "userId1", 
        "userId2", 
        "userId3", 
        "userId2"
    ]
},
{
    "_id" : "userId1",
    "name" : "Derek",
    "age" : 34
},
{
    "_id" : "userId2",
    "name" : "Homer",
    "age" : 44
},
{
    "_id" : "userId3",
    "name" : "Bobby",
    "age" : 12
}

我的查询:

db.user.aggregate(
    [
        {
            $match: { "_id": ObjectId("573b09e6322304d5e7c6256e") }
        },
        {
            $lookup:
            {
                from: "user",
                localField: "list",
                foreignField: "_id",
                as: "listData"
            }
        }
    ]
)

我需要按ID查找一个用户,并将已加入的列表数据作为ID /值对象:

{
    "_id" : ObjectId("573b09e6322304d5e7c6256e"),
    "name" : "John",
    "age" : 30,
    "list" : [ 
        "userId1", 
        "userId2", 
        "userId3", 
        "userId2"
    ],
    "listData" : {
        "userId1": {
            "_id" : "userId1",
            "name" : "Derek",
            "age" : 34
        }, 
        "userId2": {
            "_id" : "userId2",
            "name" : "Homer",
            "age" : 44
        }, 
        "userId3": {
            "_id" : "userId3",
            "name" : "Bobby",
            "age" : 12
        }
    ]
}

但是我得到了listData作为数组:

{
    "_id" : ObjectId("573b09e6322304d5e7c6256e"),
    "name" : "John",
    "age" : 30,
    "list" : [ 
        "userId1", 
        "userId2", 
        "userId3", 
        "userId2"
    ],
    "listData" : [ 
        {
            "_id" : "userId1",
            "name" : "Derek",
            "age" : 34
        }, 
        {
            "_id" : "userId2",
            "name" : "Homer",
            "age" : 44
        }, 
        {
            "_id" : "userId3",
            "name" : "Bobby",
            "age" : 12
        }
    ]
}

我需要更改以将数组作为具有键作为ID的对象吗?数据库版本v4.0.2

1 个答案:

答案 0 :(得分:3)

您可以使用$addFieldslistData变成一个对象。在此之前,您应该使用$map将数组转换为k-v对数组,然后可以使用$arrayToObjec t动态生成新密钥,请尝试:

db.col.aggregate([
    {
            $match: { "_id": ObjectId("573b09e6322304d5e7c6256e") }
    },
    {
        $lookup:
        {
            from: "user",
            localField: "list",
            foreignField: "_id",
            as: "listData"
        }
    },
    {
        $addFields: {
            listData: {
                $arrayToObject: {
                    $map: {
                        input: "$listData",
                        as: "user",
                        in: {
                            k: "$$user._id",
                            v: "$$user"
                        }
                    }
                }
            }
        }
    }
])