1

Table "user":

{
    "_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
}

My query:

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

I need to findOne user by id with joined list data as id/value object:

{
    "_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
        }
    ]
}

But I got listData as array:

{
    "_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
        }
    ]
}

What i need to change to get array as object with keys as ids? db version v4.0.2

1 Answer 1

4

You can use $addFields to turn listData into an object. Before that you should use $map to transform an array into an array of k-v pairs and then you can use $arrayToObject to generate new keys dynamically, try:

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"
                        }
                    }
                }
            }
        }
    }
])
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.