From 1d0358e3e95e163b7187dad8c3230fa62934f1bc Mon Sep 17 00:00:00 2001 From: Steve Renaker Date: Fri, 18 Nov 2016 16:51:00 -0800 Subject: [PATCH] DOCS-9337: $switch aggregation operator --- .../ref-toc-aggregation-conditional.yaml | 7 + source/reference/operator/aggregation/and.txt | 2 + .../reference/operator/aggregation/switch.txt | 203 ++++++++++++++++++ 3 files changed, 212 insertions(+) create mode 100644 source/reference/operator/aggregation/switch.txt diff --git a/source/includes/ref-toc-aggregation-conditional.yaml b/source/includes/ref-toc-aggregation-conditional.yaml index d46f6719634..8ae8a940bc0 100644 --- a/source/includes/ref-toc-aggregation-conditional.yaml +++ b/source/includes/ref-toc-aggregation-conditional.yaml @@ -14,4 +14,11 @@ description: | null result. Null result encompasses instances of undefined values or missing fields. Accepts two expressions as arguments. The result of the second expression can be null. +--- +name: :expression:`$switch` +file: /reference/operator/aggregation/switch +description: | + 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. ... diff --git a/source/reference/operator/aggregation/and.txt b/source/reference/operator/aggregation/and.txt index 340a25c0dd3..075a4d08641 100644 --- a/source/reference/operator/aggregation/and.txt +++ b/source/reference/operator/aggregation/and.txt @@ -28,6 +28,8 @@ Definition For more information on expressions, see :ref:`aggregation-expressions`. +.. _and-boolean-behavior: + Behavior -------- diff --git a/source/reference/operator/aggregation/switch.txt b/source/reference/operator/aggregation/switch.txt new file mode 100644 index 00000000000..76dd28db95e --- /dev/null +++ b/source/reference/operator/aggregation/switch.txt @@ -0,0 +1,203 @@ +===================== +$switch (aggregation) +===================== + +.. default-domain:: mongodb + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +Definition +---------- + +.. expression:: $switch + + .. versionadded:: 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. + + :expression:`$switch` has the following syntax: + + .. code-block:: javascript + + $switch: { + branches: [ + { case: , then: }, + { case: , then: }, + ... + ], + default: + } + + The objects in the ``branches`` array must contain only a ``case`` + field and a ``then`` field. + + .. list-table:: + :header-rows: 1 + :widths: 30 65 + + * - Operand + - Description + + * - ``branches`` + + - An array of control branch documents. Each branch is a + document with the following fields: + + - ``case`` + Can be any valid :ref:`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 :ref:`here`. + + - ``then`` + Can be any valid :ref:`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, :expression:`$switch` + returns an error. + +Behavior +-------- + +The various case statements do not need to be mutually exclusive. +:expression:`$switch` executes the first branch it finds which +evaluates to ``true``. If none of the branches evaluates to true, +:expression:`$switch` executes the ``default`` option. + +The following conditions cause :expression:`$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``. + +.. list-table:: + :header-rows: 1 + :widths: 80 20 + + * - Example + - Results + + * - .. code-block:: javascript + + { + $switch: { + branches: [ + { case: { $eq: [ 0, 5 ] }, then: "equals" }, + { case: { $gt: [ 0, 5 ] }, then: "greater than" }, + { case: { $lt: [ 0, 5 ] }, then: "less than" } + ] + } + } + + - ``"less than"`` + + * - .. code-block:: javascript + + { + $switch: { + branches: [ + { case: { $eq: [ 0, 5 ] }, then: "equals" }, + { case: { $gt: [ 0, 5 ] }, then: "greater than" } + ], + default: "Did not match" + } + } + + - ``"Did not match"`` + + * - .. code-block:: javascript + + { + $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: + +.. code-block:: javascript + + { "_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 :expression:`$switch` to +display a particular message based on each student's average score. + +.. code-block:: javascript + + 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: + +.. code-block:: javascript + + { "_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!" }