From fd8d0bf04bf1c24fc5329600cab6b16f5107c8ab Mon Sep 17 00:00:00 2001 From: Dave Cuthbert Date: Tue, 29 Dec 2020 13:04:34 -0500 Subject: [PATCH] DOCS-13883 add random number generator --- source/includes/extracts-agg-operators.yaml | 7 + source/reference/operator/aggregation.txt | 12 +- .../reference/operator/aggregation/rand.txt | 171 ++++++++++++++++++ .../reference/operator/aggregation/sample.txt | 5 + .../operator/query-miscellaneous.txt | 39 ++++ source/reference/operator/query.txt | 57 +++--- source/reference/operator/query/rand.txt | 65 +++++++ 7 files changed, 330 insertions(+), 26 deletions(-) create mode 100644 source/reference/operator/aggregation/rand.txt create mode 100644 source/reference/operator/query-miscellaneous.txt create mode 100644 source/reference/operator/query/rand.txt diff --git a/source/includes/extracts-agg-operators.yaml b/source/includes/extracts-agg-operators.yaml index e08574d4c61..ae7101d16b1 100644 --- a/source/includes/extracts-agg-operators.yaml +++ b/source/includes/extracts-agg-operators.yaml @@ -489,12 +489,19 @@ content: | * - Name - Description + * - :expression:`$rand` + - Returns a random float between 0 and 1 + + .. versionadded:: 4.4.2 + * - :expression:`$sampleRate` - Randomly select documents at a given rate. Although the exact number of documents selected varies on each run, the quantity chosen approximates the sample rate expressed as a percentage of the total number of documents. + + .. versionadded:: 4.4.2 --- ref: agg-operators-objects diff --git a/source/reference/operator/aggregation.txt b/source/reference/operator/aggregation.txt index e2f60776cf9..b533d59dfc5 100644 --- a/source/reference/operator/aggregation.txt +++ b/source/reference/operator/aggregation.txt @@ -647,7 +647,13 @@ Alphabetical Listing of Expression Operators * - :expression:`$radiansToDegrees` - Converts a value from radians to degrees. - + + + * - :expression:`$rand` + + - Returns a random float between 0 and 1. + + .. versionadded:: 4.4.2 * - :expression:`$range` @@ -718,7 +724,8 @@ Alphabetical Listing of Expression Operators chosen approximates the sample rate expressed as a percentage of the total number of documents. - + .. versionadded:: 4.4.2 + * - :expression:`$second` - Returns the seconds for a date as a number between 0 and 60 @@ -1044,6 +1051,7 @@ Alphabetical Listing of Expression Operators /reference/operator/aggregation/pow /reference/operator/aggregation/push /reference/operator/aggregation/radiansToDegrees + /reference/operator/aggregation/rand /reference/operator/aggregation/range /reference/operator/aggregation/reduce /reference/operator/aggregation/regexFind diff --git a/source/reference/operator/aggregation/rand.txt b/source/reference/operator/aggregation/rand.txt new file mode 100644 index 00000000000..600d546937d --- /dev/null +++ b/source/reference/operator/aggregation/rand.txt @@ -0,0 +1,171 @@ +=================== +$rand (aggregation) +=================== + +.. default-domain:: mongodb + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +Definition +---------- + +.. expression:: $rand + + .. versionadded:: 4.4.2 + + Returns a random float between 0 and 1 each time it is called. + + :expression:`$rand` has the following syntax: + + .. code-block:: javascript + + { $rand: {} } + + The :expression:`$rand` operator doesn't take any arguments. + +Behavior +-------- +Each time ``$rand`` is called it will return a floating point value +that has up to 17 digits after the decimal point. Trailing 0s are +dropped so the actual number of digits may vary. + +Examples +-------- + +This code initializes a ``randomSamples`` collection with 100 documents +that is used in the following examples. + +.. code-block:: javascript + + N = 100 + bulk = db.randomSamples.initializeUnorderedBulkOp() + for ( i = 0; i < N; i++) { bulk.insert( {_id: i, random: 0 } ) } + bulk.execute() + + +Usage with Update Queries +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``$rand`` operator can be used with update query operations. In +this example :method:`~db.collection.updateMany()` uses the ``$rand`` +operator to insert a different random number into each document +in the ``randomSamples`` collection. + +.. code-block:: javascript + + db.randomSamples.updateMany( + {}, + [ + { $set: { "random": { $rand: {} } } } + ] + ) + +We can use :pipeline:`$project` to see the output. The +:pipeline:`$limit` stage halts the pipeline after the third document. + +.. code-block:: javascript + + db.randomSamples.aggregate( + [ + { $project: {_id: 0, random: 1 } }, + { $limit: 3 } + ] + ) + +The output shows the random values. + +.. code-block:: javascript + :copyable: false + + { "random" : 0.8751284485870464 } + { "random" : 0.515147067802108 } + { "random" : 0.3750004525681561 } + +Rounding to Control the Number of Output Digits +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want a shorter random value, consider using :expression:`$round`. +Note that the :pipeline:`$set` stage updates the document, if ``$rand`` +is called in a :pipeline:`$project` stage the underlying document is +not modified. + +.. code-block:: javascript + + db.randomSamples.aggregate( + [ + { $match: {} }, + { $set: { rounded: { $round: [ "$random", 4 ] } } }, + { $out: "randomSamples" } + ] + ) + +The :pipeline:`$project` stage displays the original and rounded value +for each document. + +.. code-block:: javascript + + db.randomSamples.aggregate( + [ + { $project: {_id:0, random:1, rounded: 1 } }, + { $limit: 3 } + ] + ) + +The update documents look like this: + +.. code-block:: javascript + :copyable: false + + { "random" : 0.8751284485870464, "rounded" : 0.8751 } + { "random" : 0.515147067802108, "rounded" : 0.5151 } + { "random" : 0.3750004525681561, "rounded" : 0.375 } + +.. note:: + + Like ``$rand``, the value returned by the ``$round`` operator does + not include any trailing 0s so the number of digits returned may + vary. + +Selecting Random Items From a Collection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``$rand`` operator can be used in an aggregation pipeline to select +random documents from a collection. In this example we use ``$rand`` to +select about half the documents in the ``randomSamples`` collection. + +.. code-block:: javascript + + db.randomSamples.aggregate( + [ + { $match: { $expr: { $lt: [0.5, {$rand: {} } ] } } }, + { $count: "numMatches" } + ] + ) + +There are 100 documents in ``randomSamples``. Running the sample code 5 +times produces the following output which approaches the expected value +of 50 matches in a collection this size. + +.. code-block:: javascript + :copyable: false + + { "numMatches" : 49 } + { "numMatches" : 52 } + { "numMatches" : 54 } + { "numMatches" : 48 } + { "numMatches" : 59 } + +.. note:: + + This example shows that the number of documents selected is + different each time. If you need to select an exact number of + documents, consider using :pipeline:`$sample` instead of ``$rand``. + +.. seealso:: + + :query:`$rand (query) <$rand>`, :pipeline:`$sample`, :expression:`$round` + diff --git a/source/reference/operator/aggregation/sample.txt b/source/reference/operator/aggregation/sample.txt index 1ce09b3af4a..c6d1e9ac7bd 100644 --- a/source/reference/operator/aggregation/sample.txt +++ b/source/reference/operator/aggregation/sample.txt @@ -74,3 +74,8 @@ collection: ) The operation returns three random documents. + +.. seealso:: + + :expression:`$rand (aggregation) <$rand>` + diff --git a/source/reference/operator/query-miscellaneous.txt b/source/reference/operator/query-miscellaneous.txt new file mode 100644 index 00000000000..aa2fa515843 --- /dev/null +++ b/source/reference/operator/query-miscellaneous.txt @@ -0,0 +1,39 @@ +============================= +Miscellaneous Query Operators +============================= + +.. default-domain:: mongodb + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +.. include:: /includes/extracts/operators-toc-explanation.rst + +.. list-table:: + :widths: 25,75 + :header-rows: 1 + + * - Name + + - Description + + * - :query:`$comment` + + - Adds a comment to a query predicate. + + * - :query:`$rand` + + - Generates a random float between 0 and 1. + + .. versionadded:: 4.4.2 + + +.. toctree:: + :titlesonly: + :hidden: + + /reference/operator/query/comment + /reference/operator/query/rand diff --git a/source/reference/operator/query.txt b/source/reference/operator/query.txt index efd83e42d26..14f86bbd4bc 100644 --- a/source/reference/operator/query.txt +++ b/source/reference/operator/query.txt @@ -10,6 +10,7 @@ Query and Projection Operators :depth: 1 :class: singlecol + .. include:: /includes/extracts/operators-toc-explanation.rst .. _query-selectors: @@ -23,6 +24,7 @@ Comparison .. only:: website .. include:: /includes/fact-comparison-order.rst + .. list-table:: :widths: 30,70 :header-rows: 1 @@ -299,64 +301,71 @@ Bitwise /reference/operator/query-bitwise -Comments -~~~~~~~~ + +.. _query-projection-operators: + +Projection Operators +-------------------- .. only:: website .. list-table:: - :widths: 30,70 + :widths: 25,75 :header-rows: 1 * - Name - Description - * - :query:`$comment` + * - :projection:`$` - - Adds a comment to a query predicate. + - Projects the first element in an array that matches the query condition. + * - :projection:`$elemMatch` + + - Projects the first element in an array that matches the specified :projection:`$elemMatch` condition. + + * - :projection:`$meta` + + - Projects the document's score assigned during :query:`$text` operation. + + * - :projection:`$slice` + + - Limits the number of elements projected from an array. Supports skip and limit slices. .. toctree:: :titlesonly: :hidden: - /reference/operator/query/comment + /reference/operator/projection -.. _query-projection-operators: +.. _query-miscelaneous-operators: -Projection Operators --------------------- +Miscellaneous Operators +----------------------- .. only:: website .. list-table:: - :widths: 30,70 + :widths: 25,75 :header-rows: 1 * - Name - Description - * - :projection:`$` - - - Projects the first element in an array that matches the query condition. - - * - :projection:`$elemMatch` - - - Projects the first element in an array that matches the specified :projection:`$elemMatch` condition. - - * - :projection:`$meta` - - - Projects the document's score assigned during :query:`$text` operation. + * - :query:`$comment` - * - :projection:`$slice` + - Adds a comment to a query predicate. - - Limits the number of elements projected from an array. Supports skip and limit slices. + * - :query:`$rand` + - Generates a random float between 0 and 1. .. toctree:: :titlesonly: :hidden: - /reference/operator/projection + /reference/operator/query-miscellaneous + + diff --git a/source/reference/operator/query/rand.txt b/source/reference/operator/query/rand.txt new file mode 100644 index 00000000000..c5af1b5fb32 --- /dev/null +++ b/source/reference/operator/query/rand.txt @@ -0,0 +1,65 @@ +===== +$rand +===== + +.. default-domain:: mongodb + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +Definition +---------- + +.. query:: $rand + +.. versionadded:: 4.4.2 + +:query:`$rand` returns a random float between 0 and 1. + +:query:`$rand` has the following syntax: + +.. code-block:: javascript + + { $rand: {} } + +Examples +-------- + +This code creates a small collection of 100 documents. We will +use ``$rand`` to select random documents from the collection. + +.. code-block:: javascript + + N = 100 + bulk = db.samples.initializeUnorderedBulkOp() + for (i = 0; i < N; i++) { bulk.insert({_id: i, r: 0}) } + bulk.execute() + +In this example we use ``$rand`` to select about half the documents. + +.. code-block:: javascript + + db.samples.find( + { $expr: { $lt: [0.5, {$rand: {} } ] } } + ).count() + +Running this :dbcommand:`find` operation five times returns five random +values that approach the number 50, which is the expected value for a +collection of this size. For example: + +.. code-block:: javascript + :copyable: false + + 51 + 53 + 49 + 45 + 47 + +.. seealso:: + + :expression:`$rand (aggregation) <$rand>` +