$switch (aggregation)

Definition

  • $switch

New in version 3.4.

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

$switch has the following syntax:

  1. $switch: {
  2. branches: [
  3. { case: <expression>, then: <expression> },
  4. { case: <expression>, then: <expression> },
  5. ...
  6. ],
  7. default: <expression>
  8. }

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

OperandDescriptionbranchesAn array of control branch documents. Each branch is adocument with the following fields:

    • case
    • Can be any valid expression that resolves to aboolean. If the result is not a boolean, it iscoerced to a boolean value. More information about howMongoDB evaluates expressions as either true or falsecan be found here.
    • then
    • Can be any valid expression.The branches array must contain at least one branchdocument.defaultOptional. The path to take if no branch case expressionevaluates to true.

Although optional, if default is unspecified and nobranch case evaluates to true, $switchreturns an error.

Behavior

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

The following conditions cause $switch to fail with anerror:

  • The branches field is missing or is not an array with at leastone entry.
  • An object in the branches array does not contain a casefield.
  • An object in the branches array does not contain a thenfield.
  • An object in the branches array contains a field other thancase or then.
  • No default is specified and no case evaluates to true.
ExampleResults
  1. { $switch: { branches: [ { case: { $eq: [ 0, 5 ] }, then: "equals" }, { case: { $gt: [ 0, 5 ] }, then: "greater than" }, { case: { $lt: [ 0, 5 ] }, then: "less than" } ] }}
"less than"
  1. { $switch: { branches: [ { case: { $eq: [ 0, 5 ] }, then: "equals" }, { case: { $gt: [ 0, 5 ] }, then: "greater than" } ], default: "Did not match" }}
"Did not match"
  1. { $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:

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

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

  1. db.grades.aggregate( [
  2. {
  3. $project:
  4. {
  5. "name" : 1,
  6. "summary" :
  7. {
  8. $switch:
  9. {
  10. branches: [
  11. {
  12. case: { $gte : [ { $avg : "$scores" }, 90 ] },
  13. then: "Doing great!"
  14. },
  15. {
  16. case: { $and : [ { $gte : [ { $avg : "$scores" }, 80 ] },
  17. { $lt : [ { $avg : "$scores" }, 90 ] } ] },
  18. then: "Doing pretty well."
  19. },
  20. {
  21. case: { $lt : [ { $avg : "$scores" }, 80 ] },
  22. then: "Needs improvement."
  23. }
  24. ],
  25. default: "No scores found."
  26. }
  27. }
  28. }
  29. }
  30. ] )

The operation returns the following:

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

See also

$cond