CharlesR
CharlesR

Reputation: 53

MongoDB - Array of object filter with condition

I have a json file that look like this in my collection :

[
   {
      "change":"00001",
      "patchset":"4"
   },
   //etc
]

Two different object can have the same "change" properties. So first I want to group them by "change" properties and inside this group I want the highest value of the "patchset" properties. I have managed to do this easily with this command

db.collections.aggregate([{$group:{_id:"$change",patchset_max:{$max:"$patchset"}}}])

but then, and this is where I lost it, with this max patchset, I want to get all the objects where object.patchset = max_patchset but still in the group array.

I tried with $filter and $match and then nested $group but nothing works,

Do you guys have any idea ?

Thanks

Upvotes: 1

Views: 1673

Answers (2)

sofcal
sofcal

Reputation: 490

EDIT Answer above is correct, but if on Mongo 3.2, here's an alternative

db.collection.aggregate([{ 
    $group: { _id: "$change", patchset: { $push: "$$ROOT" }, patchset_max:{ $max:"$patchset" } } 
},{ 
    $project: {
        patchset: {
            $filter: { 
                input: '$patchset',
                as: 'ps',
                cond: { $eq: ['$$ps.patchset', '$patchset_max'] }
            }
        }
    }
}])

Upvotes: 2

mickl
mickl

Reputation: 49985

You need to use $$ROOT which is a special variable that represents whole document to get all the items for each group and then you can use $addFields to overwrite existing array and $filter to get only those docs that have patchset equal to patchset_max. Try:

db.collection.aggregate([
    {
        $group: {
            _id: "$change",
            patchset_max:{$max:"$patchset"},
            docs: { $push: "$$ROOT" }
        }
    },
    {
        $addFields: {
            docs: {
                $filter: {
                    input: "$docs",
                    as: "doc",
                    cond: {
                        $eq: [ "$patchset_max", "$$doc.patchset" ]
                    }
                }
            }
        }
    }
])

Sample playground here

Upvotes: 3

Related Questions