Reputation: 11154
I would like to exclude a field from a mongo db aggergtion pipeline, after reading the docs, I thought I needed to specify either 1 or 0 to keep the field or not (cf. http://docs.mongodb.org/manual/reference/operator/aggregation/project/)
So I tried the following (using node.js mongoose, but the syntax is quite the same as plain mongo):
aggregate.match({ date: { $gte : today } });
aggregate.sort('-date');
aggregate.group({
_id: '$name',
date: { $first: '$date' },
user: { $first: '$user' },
app: { $first: '$app' }
});
aggregate.project({
_id: 1,
last: { $cond: [ { $eq : [ '$_id', 'undo' ] }, '$date', 0 ] },
user: { $cond: [ { $eq : [ '$_id', 'undo' ] }, '$user', 0 ] },
app: { $cond: [ { $eq : [ '$_id', 'undo' ] }, '$app', 0 ] }
});
But doing that, I end with documents like this:
[
{
_id: 'devices',
user: 0,
app: 0,
last: 0
},
{
_id: 'undo',
user: 'test',
app: 'truc',
last: Mon Jan 26 2015 16:21:53 GMT+0100 (CET)
}
]
I want the user
, app
and date
to appear only when _id
is undo
.
How to achieve it?
Thanks!
Upvotes: 10
Views: 5148
Reputation: 336
Starting in mongoDB 3.6, you can use the REMOVE variable to exclude fields conditionally.
In your particular case, the project stage should look like this:
aggregate.project({
_id: 1,
last: { $cond: [ { $eq : [ '$_id', 'undo' ] }, '$date', '$$REMOVE' ] },
user: { $cond: [ { $eq : [ '$_id', 'undo' ] }, '$user', '$$REMOVE' ] },
app: { $cond: [ { $eq : [ '$_id', 'undo' ] }, '$app', '$$REMOVE' ] }
});
Upvotes: 9
Reputation: 21
I think it's not possible yet.
Error message from the shell when trying to exclude a non-_id field :
The top-level _id field is the only field currently supported for exclusion
Upvotes: 2