How to run different stages, according to the conditions of the result of a $match, in MongoDB?

Viewed 27

How to run different stages, depending on the conditions of the result of a $match, to avoid requesting the database several times. First I find a user, if the user information is x I need to make another match, if it is y the match will be different:

const user = users.aggregate([
    { $match: { _id: _id } }
])

if (user.selectedPark) {
    if (user.isAdmin) {
        // indexed lookup
    } else {
        // indexed lookup
    }
} else {
    // indexed lookup
}
1 Answers

Use the $facet stage to create "sub-pipelines".

Example:
a users collection with the following documents

[
    {
      name: "Jack",
      admin: true,
      _id: 1,
      age: 19
    },
    {
      name: "Sam",
      admin: true,
      _id: 2,
      age: 22
    },
    {
      name: "John",
      _id: 3,
      age: 11,
      admin: false
    }
]

Create an aggregation pipeline with a $facet stage after the first $match stage with two sub-pipelines. The two sub-piplines each match on different values of admin field and define different operations. Run the following aggregation:

db.users.aggregate([
  {
    "$match": {
      "_id": 1
    }
  },
  {
    "$facet": {
      "admin": [
        {
          "$match": {
            "admin": true
          }
        },
        {
          "$project": {
            "admin": 1
          }
        }
      ],
      "nonadmin": [
        {
          "$match": {
            "admin": false
          }
        },
        {
          "$project": {
            "admin": 1,
            "name": 1,
            "age": 1
          }
        }
      ]
    }
  }
])

Returns the following:

[
  {
    "admin": [
      {
        "admin": true
      }
    ],
    "nonadmin": []
  }
]

The value of each key in $facet will be an array because each key represents a "sub-pipeline".

Related