Navigation

$switch (aggregation)

On this page

Definition

$switch

New in version 3.4.

Evaluates a series of case expressions. When it finds an expression which evaluates to true, $switch executes a specified expression and breaks out of the control flow.

$switch has the following syntax:

$switch: {
   branches: [
      { case: <expression>, then: <expression> },
      { case: <expression>, then: <expression> },
      ...
   ],
   default: <expression>
}

The objects in the branches array must contain only a case field and a then field.

Operand Description
branches

An array of control branch documents. Each branch is a document with the following fields:

  • case
    Can be any valid expression that resolves to a boolean. If the result is not a boolean, it is coerced to a boolean value. More information about how MongoDB evaluates expressions as either true or false can be found here.
  • then
    Can be any valid expression.

The branches array must contain at least one branch document.

default

Optional. The path to take if no branch case expression evaluates to true.

Although optional, if default is unspecified and no branch case evaluates to true, $switch returns an error.

Behavior

The various case statements do not need to be mutually exclusive. $switch executes the first branch it finds which evaluates to true. If none of the branches evaluates to true, $switch executes the default option.

The following conditions cause $switch to fail with an error:

  • The branches field is missing or is not an array with at least one entry.
  • An object in the branches array does not contain a case field.
  • An object in the branches array does not contain a then field.
  • An object in the branches array contains a field other than case or then.
  • No default is specified and no case evaluates to true.
Example Results
{
   $switch: {
      branches: [
         { case: { $eq: [ 0, 5 ] }, then: "equals" },
         { case: { $gt: [ 0, 5 ] }, then: "greater than" },
         { case: { $lt: [ 0, 5 ] }, then: "less than" }
      ]
   }
}
"less than"
{
   $switch: {
      branches: [
         { case: { $eq: [ 0, 5 ] }, then: "equals" },
         { case: { $gt: [ 0, 5 ] }, then: "greater than" }
      ],
      default: "Did not match"
   }
}
"Did not match"
{
   $switch: {
      branches: [
         { case: "this is true", then: "first case" },
         { case: false, then: "second case" }
      ],
      default: "Did not match"
   }
}
"First case"

Example

A collection named grades contains the following documents:

{ "_id" : 1, "name" : "Susan Wilkes", "scores" : [ 87, 86, 78 ] }
{ "_id" : 2, "name" : "Bob Hanna", "scores" : [ 71, 64, 81 ] }
{ "_id" : 3, "name" : "James Torrelio", "scores" : [ 91, 84, 97 ] }

The following aggregation operation uses $switch to display a particular message based on each student’s average score.

db.grades.aggregate( [
  {
    $project:
      {
        "name" : 1,
        "summary" :
        {
          $switch:
            {
              branches: [
                {
                  case: { $gte : [ { $avg : "$scores" }, 90 ] },
                  then: "Doing great!"
                },
                {
                  case: { $and : [ { $gte : [ { $avg : "$scores" }, 80 ] },
                                   { $lt : [ { $avg : "$scores" }, 90 ] } ] },
                  then: "Doing pretty well."
                },
                {
                  case: { $lt : [ { $avg : "$scores" }, 80 ] },
                  then: "Needs improvement."
                }
              ],
              default: "No scores found."
            }
         }
      }
   }
] )

The operation returns the following:

{ "_id" : 1, "name" : "Susan Wilkes", "summary" : "Doing pretty well." }
{ "_id" : 2, "name" : "Bob Hanna", "summary" : "Needs improvement." }
{ "_id" : 3, "name" : "James Torrelio", "summary" : "Doing great!" }