Rafa Acioly
Rafa Acioly

Reputation: 636

How to group mongo doc based on key inside an array?

I've a collection that have this documents:

{
    sku: 1,
    values: [{x: false, z: 100}]
}
{
    sku: 1,
    values: [{z: 100}]
}
{
    sku: 2
    values: [{x: false, z: 100}]
}

Note that the document with sku 2 is not duplicated but it have the key x in a object inside an array.

How do i query the documents grouping by sku and get the one that does not have the key x but at the same time also get the sku that is not duplicated but have the x key?

The result that i expect is:

{
    sku: 1,
    values: [{z: 100}]
}
{
    sku: 2,
    values: [{x: false, x: 100}]
}

I want to ignore a document if it is duplicated by the key sku and have the keyx: false but if the document is not duplicated by sku to get it anyway

Upvotes: 1

Views: 258

Answers (1)

mickl
mickl

Reputation: 49985

So rephrasing your requirements: you want to filter out all values with x: false if there's more than one document with particular sku

You need Aggregation Framework's $group to get all the data for single sku. Then you can run $reduce with $concatArrays to flatten values array and $filter as a last step to apply your business rule:

db.collection.aggregate([
    {
        $group: {
            _id: "$sku",
            count: { $sum: 1 },
            values: { $push: "$values" }
        }
    },
    {
        $addFields: {
            values: {
                $reduce: {
                    input: "$values",
                    initialValue: [],
                    in: { $concatArrays: [ "$$value", "$$this" ] }
                }
            }
        }
    },
    {
        $project: {
            _id: 0,
            sku: "$_id",
            values: {
                $filter: {
                    input: "$values",
                    cond: {
                        $or: [
                            { $eq: [ "$count", 1 ] },
                            { $ne: [ "$$this.x", false ] }
                        ]
                    }
                }
            }
        }
    }
])

Mongo Playground

Upvotes: 1

Related Questions