Search code examples
mongodbaggregation-frameworkprojection

Conditionally include a field (_id or other) in mongodb project aggregation?


I've got a mongodb aggregation pipeline with a $project stage and I'd like to include certain fields only if conditions are met. Specifically, I'd like to exclude the _id in one condition and include a second field 'second_id' in the other condition.

I know that it's not possible (yet) to exclude fields from a mongodb $project, but is it possible to conditionally include them?

Is there a way to conditionally exclude the _id field? It accepts a 0 or 1, but what if I want to determine that 0 or 1 based on an if statement. How would this be done?

Pseudocode for _id:

$project: { _id: { $ifNull: [ "$user_id", 0 ] } }

The main use of this would be to use the doc.user_id as the result _id, or allow mongodb to create a new autoincrement _id if that user_id is null.


Solution

  • There isn't a way currently to do this within the $project stage, but you can use the $redact stage to remove the field conditionally (i.e. you set the value to 0 like you are doing in your example.

    db.collection.aggregate(
      ... matching and stuff ...
      {$project: { _id: { $ifNull: [ "$user_id", 0 ] } }},
      {$redact: {
      {$cond: {
        if: { $eq: [ "$user_id", 0 ] },
        then: '$$PRUNE',
        else: '$$DESCEND'
      }}
    }