danyolgiax
danyolgiax

Reputation: 13086

Aggregate in MongoDB excluding array item

I need to group these docs by taxonomy array but I've to exclude from group the "term3" item from the first Doc. (My situation is more complicated in a real app but this example fits.)

[
    {
        "_id": "1",
        "Taxonomy": [
            {
                "Key": "1", "Term": "term1"
            },
            {
                "Key": "2", "Term": "term2"
            },
            {
                "Key": "3", "Term": "term3"
            }
        ]
    },
    {
        "_id": "2",
        "Taxonomy": [
            {
                "Key": "1", "Term": "term1"
            },
            {
                "Key": "2", "Term": "term2"
            }
        ]
    },
    {
        "_id": "3",
        "Taxonomy": [
            {
                "Key": "1", "Term": "term1"
            },
            {
                "Key": "2", "Term": "term2"
            }
        ]
    }
]

This command generates two nodes due to the "term3" item:

{$group: {"_id" :"$Taxonomy","Posts" : { "$addToSet" : { "_id" : "$_id"}}}}

It is possible to unwind, match and then re-group documents or there is a simple way?

Upvotes: 2

Views: 1280

Answers (1)

Asya Kamsky
Asya Kamsky

Reputation: 42352

Running this aggregation:

db.terms.aggregate([
    {$unwind:"$Taxonomy"},
    {$match:{"Taxonomy.Term":{$ne:"term3"}}},
    {$group:{_id:"$_id",Taxonomy:{$push:"$Taxonomy"}}}
])

Will produce this result:

{ "_id" : "2", "Taxonomy" : [ { "Key" : "1", "Term" : "term1" }, { "Key" : "2", "Term" : "term2" } ] }
{ "_id" : "3", "Taxonomy" : [ { "Key" : "1", "Term" : "term1" }, { "Key" : "2", "Term" : "term2" } ] }
{ "_id" : "1", "Taxonomy" : [ { "Key" : "1", "Term" : "term1" }, { "Key" : "2", "Term" : "term2" } ] }

If you then need to do further grouping/processing, you can add more stages. If you needed to exclude based on Key rather than Term then you can adjust $match stage. If you want to exclude everything other than term1 and term2 you would change the $ne to be $in:[<list-of-values-to-keep>].

Upvotes: 4

Related Questions