1

After a few pipeline stages, I came up with following sample result which is one document. If the videos.views.userId contains 10, I need to indicate videos.isWatched = true else false. We can use $unwind, check the condition, then group it.

This is sample output, The original document contains a lot of field, so I just like to do with less code unless I need to unwind Is there any way to do without unwind("videos")?

[
    {
        "_id":"someId",
        "videos":[
            {
                "_id":"1",
                "name":"A",
                "views":[
                    {
                        "userId":10,
                        "group":"X"
                    }
                ]
            },
            {
                "_id":"2",
                "name":"B",
                "views":[
                    {
                        "userId":20,
                        "group":"Y"
                    }
                ]
            }
        ],
        "Assessment":[
            {
                "_id":"22",
                "title": "Hello world"
            }
        ]
    }
]

Expected result

[
    {
        "_id":"someId",
        "videos":[
            {
                _id:"1",
                name:"A",
                views:[
                    {
                        userId:10,
                        group:"X"
                    }
                ],
                "isWatched":true
            },
            {
                _id:"2",
                name:"B",
                views:[
                    {
                        userId:20,
                        group:"Y"
                    }
                ],
                "isWatched":false
            }
        ],
        "Assessment":[
            {
                _id:"22",
                title: "Hello world"
            }
        ]
    }
]

1 Answer 1

1

You can use $map along with $mergeObjects to add a new field to an existing array. $anyElementTrue can be used to determine whether there's any userId equal to 10:

db.collection.aggregate([
    {
        $addFields: {
            videos: {
                $map: {
                    input: "$videos",
                    in: {
                        $mergeObjects: [
                            "$$this",
                            { 
                                isWatched: {
                                    $anyElementTrue: {
                                        $map: { input: "$$this.views", in: { $eq: [ "$$this.userId", 10 ] } }
                                    }
                                }  
                            }
                        ]
                    }
                }
            }
        }
    }
])

Mongo Playground

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.