user6586661
user6586661

Reputation: 452

MongoDB get only matching elements from nested array

I have a collection like this:

{
_id : 123,
username : "xy",
comments : [
    {
        text : "hi",
        postdate : 123456789
    },
    {
        text : "hi1",
        postdate : 555555555
    },
    {
        text : "hi2",
        postdate : 666666666
    },
    {
        text : "hi3",
        postdate : 987654321
    }

]}

Now I want only the comments that have postdate 555555555 or higher and 987654321 or lower. I have this query, but it doesn't work:

db.post.aggregate([
{$match : {$and : [ 
{"_id": ObjectId("123")},
{"comments.posttime" : {$lte : 987654321}},
{"comments.posttime" : {$gte : 555555555}}
]}}
,{$unwind: "$comments"}]).pretty();

But when I try this it gets me all of the array elements. How should this be done?

Thank you!

Upvotes: 1

Views: 1078

Answers (2)

Prasanna Ab
Prasanna Ab

Reputation: 116

you have to unwind the comments first and then do the match. so that comments array will be flattened and match condition can filter it properly.

[{$unwind: "$comments"},{$match : {$and : [ 
{"_id": ObjectId("123")},
{"comments.posttime" : {$lte : 987654321}},
{"comments.posttime" : {$gte : 555555555}}
]}}]

this will give one row for each comment, if you want the matching comments inside the array, use aggregate on _id and $push the comments

Upvotes: 0

radhakrishnan
radhakrishnan

Reputation: 1459

Use $redact to Restricts the contents of the document,

                db.an.aggregate([{
        $redact: {
            "$cond": [{
                $and: [{
                    "$gte": [{
                            "$ifNull": ["$postdate", 555555555]
                        },
                        555555555
                    ]
                }, {
                    "$lte": [{
                            "$ifNull": ["$postdate", 987654321]
                        },
                        987654321
                    ]
                }]
            }, "$$DESCEND", "$$PRUNE"]
        }
    }]).pretty()

Upvotes: 2

Related Questions