Rafa Llorente
Rafa Llorente

Reputation: 447

Conditional unwind in MongoDb's aggregation?

I'm trying to figure out if there is a way to code a conditional unwind in MongoDB's aggregation framework.

I have an aggregation command like this:

models.Users.aggregate(
        {   // SELECT
        $project : { "sex" : 1,
                 "salesIndex":1
                }
        },
        {   // WHERE
            $match: {"salesIndex": {$gte: index}} 
        },              
        {   // GROUP BY y agregadores
            $group: {
                _id      : "$sex",
                sexCount : { $sum: 1 }
            }
        },
        { $sort: { sexCount: -1 } }
, function(err, dbres) {
         (...)
});

I'd like to add an optional filter by department. A user can be in one or more departments, here is how it looks like in the db:

user _id sex salesIndex departments {[d1, d2, d3]}

If I wanted to search for users in a particular department, I'd code an $unwind clause and then a $match by department. However I'd like to use the same aggregation command for both scenarios, something like this:

models.Users.aggregate(
        {   // SELECT
        $project : { "sex" : 1,
                 "salesIndex":1
                }
        },
        {   // WHERE
            $match: {"salesIndex": {$gte: index}} 
        },  

                    IF (filteringByDepartment){

                        $unwind departments here                            
                        $match by departmentId here
                    } 

        {   // GROUP BY y agregadores
            $group: {
                _id      : "$sex",
                sexCount : { $sum: 1 }
            }
        },
        { $sort: { sexCount: -1 } }
, function(err, dbres) {
         (...)
});

Is this possible at all, or I need 2 aggregation commands?

Upvotes: 6

Views: 9843

Answers (1)

JohnnyHK
JohnnyHK

Reputation: 312129

Build up your aggregation pipeline programmatically prior to calling aggregate:

var pipeline = [];
pipeline.push(
    {   // SELECT
    $project : { "sex" : 1,
             "salesIndex":1
            }
    },
    {   // WHERE
        $match: {"salesIndex": {$gte: index}}
    }
);
if (filteringByDepartment) {
    pipeline.push(
        { $unwind: '$departments' },
        { $match: { departments: departmentId }}
    );
}    
pipeline.push(
    {   // GROUP BY y agregadores
        $group: {
            _id      : "$sex",
            sexCount : { $sum: 1 }
        }
    },
    { $sort: { sexCount: -1 } }
);

models.Users.aggregate(pipeline, function(err, dbres) {
    //...
});

Upvotes: 10

Related Questions