Reputation: 447
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
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