mongodb aggregation with $project to conditionally exclude a field

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!

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

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' ] }
});

Solution 2

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

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply