$switch (aggregation)
On this page
Definition
$switch
-
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 acase
field and athen
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 aboolean
, 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.
branches
array must contain at least one branch document.default
Optional. The path to take if no branch case
expression evaluates totrue
.
Although optional, ifdefault
is unspecified and no branchcase
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 acase
field. -
An object in the
branches
array does not contain athen
field. -
An object in the
branches
array contains a field other thancase
orthen
. -
No
default
is specified and nocase
evaluates totrue
.
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!" }