Skip to content

Commit dbf914b

Browse files
mungitoperritojeff-allen-mongo
authored andcommitted
DOCS-13883 add random number generator
1 parent 12935ac commit dbf914b

File tree

8 files changed

+199
-134
lines changed

8 files changed

+199
-134
lines changed

source/includes/extracts-agg-operators.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,6 @@ content: |
114114
* - :expression:`$pow`
115115
- Raises a number to the specified exponent.
116116
117-
* - :expression:`$rand`
118-
- Returns a random value between 0 and 1
119-
120117
* - :expression:`$round`
121118
- Rounds a number to to a whole integer *or* to a specified
122119
decimal place.
@@ -492,6 +489,9 @@ content: |
492489
* - Name
493490
- Description
494491
492+
* - :expression:`$rand`
493+
- Returns a random float between 0 and 1
494+
495495
* - :expression:`$sampleRate`
496496
497497
- Randomly select documents at a given rate. Although the exact

source/reference/operator/aggregation.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,12 @@ Alphabetical Listing of Expression Operators
647647
* - :expression:`$radiansToDegrees`
648648

649649
- Converts a value from radians to degrees.
650-
650+
651+
652+
* - :expression:`$rand`
653+
654+
- Returns a random float between 0 and 1.
655+
651656

652657
* - :expression:`$range`
653658

source/reference/operator/aggregation/rand.txt

Lines changed: 124 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -17,103 +17,155 @@ Definition
1717

1818
.. versionadded:: 4.4.2
1919

20-
The :expression:`$rand` operator generates a random value between 0
21-
and 1 each time it is called.
20+
Returns a random float between 0 and 1 each time it is called.
21+
22+
:expression:`$rand` has the following syntax:
23+
24+
.. code-block:: javascript
25+
26+
{ $rand: {} }
27+
28+
The :expression:`$rand` operator doesn't take any arguments.
29+
30+
Behavior
31+
--------
32+
Each time ``$rand`` is called it will return a floating point value
33+
that has up to 17 digits after the decimal point. Trailing 0s are
34+
dropped so the actual number of digits may vary.
2235

2336
Examples
2437
--------
2538

26-
This code creates a small collection with 100 documents which we will
27-
use in these examples. (Increase the value of ``N`` if you want to
28-
experiment with larger data sets).
29-
39+
This code initializes a ``randomSamples`` collection with 100 documents
40+
that is used in the following examples.
41+
3042
.. code-block:: javascript
3143

3244
N = 100
33-
bulk = db.collection.initializeUnorderedBulkOp()
34-
for (i = 0; i < N; i++) { bulk.insert({_id: i, r: 0}) }
45+
bulk = db.randomSamples.initializeUnorderedBulkOp()
46+
for ( i = 0; i < N; i++) { bulk.insert( {_id: i, random: 0 } ) }
3547
bulk.execute()
3648

37-
Consider the following examples:
3849

39-
The ``$rand`` operator can be used in a pipeline to select random
40-
documents from a collection. In this example we use the same database
41-
and ``$rand`` to select about half the documents.
50+
Usage with Update Queries
51+
~~~~~~~~~~~~~~~~~~~~~~~~~
52+
53+
The ``$rand`` operator can be used with update query operations. In
54+
this example :method:`~db.collection.updateMany()` uses the ``$rand``
55+
operator to insert a different random number into each document
56+
in the ``randomSamples`` collection.
4257

4358
.. code-block:: javascript
4459

45-
db.collection.aggregate(
46-
[
47-
{ $match:
48-
{
49-
$expr:
50-
{
51-
$lt: [0.5, {$rand: {} } ]
52-
}
53-
}
54-
},
55-
{
56-
$count: "numMatches"
57-
}
58-
]
59-
)
60+
db.randomSamples.updateMany(
61+
{},
62+
[
63+
{ $set: { "random": { $rand: {} } } }
64+
]
65+
)
66+
67+
We can use :pipeline:`$project` to see the output. The
68+
:pipeline:`$limit` stage halts the pipeline after the third document.
6069

6170
.. code-block:: javascript
62-
:copyable: false
6371

64-
// Output of 5 runs on the sample collection
65-
{ "numMatches" : 49 }
66-
{ "numMatches" : 52 }
67-
{ "numMatches" : 54 }
68-
{ "numMatches" : 48 }
69-
{ "numMatches" : 59 }
72+
db.randomSamples.aggregate(
73+
[
74+
{ $project: {_id: 0, random: 1 } },
75+
{ $limit: 3 }
76+
]
77+
)
7078

71-
.. note::
79+
The output shows the random values.
80+
81+
.. code-block:: javascript
82+
:copyable: false
83+
84+
{ "random" : 0.8751284485870464 }
85+
{ "random" : 0.515147067802108 }
86+
{ "random" : 0.3750004525681561 }
7287

73-
This example returns different results each time. Smaller datasets
74-
show more variability in repeated runs. The number of documents
75-
selected each time approaches the expected value (in this case 50%)
76-
as the collection size grows.
88+
Rounding to Control the Number of Output Digits
89+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7790

78-
Update operations accept aggregation pipelines. In this example the
79-
``$rand`` operator is used to insert a different random number into each
80-
document in a collection.
91+
If you want a shorter random value, consider using :expression:`$round`.
92+
Note that the :pipeline:`$set` stage updates the document, if ``$rand``
93+
is called in a :pipeline:`$project` stage the underlying document is
94+
not modified.
8195

8296
.. code-block:: javascript
8397

84-
db.collection.updateMany({}, [
85-
{
86-
$set:
87-
{
88-
"r":
89-
{
90-
$rand: {}
91-
}
92-
}
93-
}
94-
]
95-
)
96-
97-
This is brief excerpt showing the results of the update:
98+
db.randomSamples.aggregate(
99+
[
100+
{ $match: {} },
101+
{ $set: { rounded: { $round: [ "$random", 4 ] } } },
102+
{ $out: "randomSamples" }
103+
]
104+
)
105+
106+
The :pipeline:`$project` stage displays the original and rounded value
107+
for each document.
98108

99109
.. code-block:: javascript
100-
:copyable: false
101-
102-
db.collection.aggregate(
103-
[
104-
{
105-
$project: {_id:0, r:1 }
106-
}
107-
]
108-
)
109-
110-
{ "r" : 0.9141450086748962 }
111-
{ "r" : 0.151174715006409 }
112-
{ "r" : 0.4311952154820518 }
113-
{ "r" : 0.08106914853292181 }
114-
...
110+
111+
db.randomSamples.aggregate(
112+
[
113+
{ $project: {_id:0, random:1, rounded: 1 } },
114+
{ $limit: 3 }
115+
]
116+
)
117+
118+
The update documents look like this:
119+
120+
.. code-block:: javascript
121+
:copyable: false
122+
123+
{ "random" : 0.8751284485870464, "rounded" : 0.8751 }
124+
{ "random" : 0.515147067802108, "rounded" : 0.5151 }
125+
{ "random" : 0.3750004525681561, "rounded" : 0.375 }
126+
127+
.. note::
128+
129+
Like ``$rand``, the value returned by the ``$round`` operator does
130+
not include any trailing 0s so the number of digits returned may
131+
vary.
132+
133+
Selecting Random Items From a Collection
134+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135+
136+
The ``$rand`` operator can be used in an aggregation pipeline to select
137+
random documents from a collection. In this example we use ``$rand`` to
138+
select about half the documents in the ``randomSamples`` collection.
139+
140+
.. code-block:: javascript
141+
142+
db.randomSamples.aggregate(
143+
[
144+
{ $match: { $expr: { $lt: [0.5, {$rand: {} } ] } } },
145+
{ $count: "numMatches" }
146+
]
147+
)
148+
149+
There are 100 documents in ``randomSamples``. Running the sample code 5
150+
times produces the following output which approaches the expected value
151+
of 50 matches in a collection this size.
152+
153+
.. code-block:: javascript
154+
:copyable: false
155+
156+
{ "numMatches" : 49 }
157+
{ "numMatches" : 52 }
158+
{ "numMatches" : 54 }
159+
{ "numMatches" : 48 }
160+
{ "numMatches" : 59 }
161+
162+
.. note::
163+
164+
This example shows that the number of documents selected is
165+
different each time. If you need to select an exact number of
166+
documents, consider using :pipeline:`$sample` instead of ``$rand``.
115167

116168
.. seealso::
117169

118-
:expression:`$let`, :query:`$rand`.
170+
:query:`$rand (query) <$rand>`, :pipeline:`$sample`, :expression:`$round`
119171

source/reference/operator/aggregation/sample.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,9 @@ collection:
7474
)
7575

7676
The operation returns three random documents.
77+
78+
.. seealso::
79+
80+
:expression:`$rand (aggregation) <$rand>`
81+
82+
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
=====================
2-
Other Query Operators
3-
=====================
1+
=============================
2+
Miscellaneous Query Operators
3+
=============================
44

55
.. default-domain:: mongodb
66

@@ -13,7 +13,7 @@ Other Query Operators
1313
.. include:: /includes/extracts/operators-toc-explanation.rst
1414

1515
.. list-table::
16-
:widths: 30,70
16+
:widths: 25,75
1717
:header-rows: 1
1818

1919
* - Name
@@ -22,16 +22,16 @@ Other Query Operators
2222

2323
* - :query:`$comment`
2424

25-
- Allows use of commented code within the query language.
25+
- Adds a comment to a query predicate.
2626

2727
* - :query:`$rand`
2828

29-
- Generates a random number between 0 and 1.
29+
- Generates a random float between 0 and 1.
30+
3031

3132
.. toctree::
32-
:titlesonly:
33-
:hidden:
33+
:titlesonly:
34+
:hidden:
3435

3536
/reference/operator/query/comment
3637
/reference/operator/query/rand
37-

source/reference/operator/query.txt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Query and Projection Operators
1010
:depth: 1
1111
:class: singlecol
1212

13+
1314
.. include:: /includes/extracts/operators-toc-explanation.rst
1415

1516
.. _query-selectors:
@@ -23,6 +24,7 @@ Comparison
2324
.. only:: website
2425

2526
.. include:: /includes/fact-comparison-order.rst
27+
2628
.. list-table::
2729
:widths: 30,70
2830
:header-rows: 1
@@ -330,22 +332,21 @@ Projection Operators
330332

331333
- Limits the number of elements projected from an array. Supports skip and limit slices.
332334

333-
334335
.. toctree::
335336
:titlesonly:
336337
:hidden:
337338

338339
/reference/operator/projection
339340

340-
.. _query-other-operators:
341+
.. _query-miscelaneous-operators:
341342

342-
Other Operators
343-
---------------
343+
Miscellaneous Operators
344+
-----------------------
344345

345346
.. only:: website
346347

347348
.. list-table::
348-
:widths: 30,70
349+
:widths: 25,75
349350
:header-rows: 1
350351

351352
* - Name
@@ -354,15 +355,15 @@ Other Operators
354355

355356
* - :query:`$comment`
356357

357-
- Allows use of commented code within the query language.
358+
- Adds a comment to a query predicate.
358359

359360
* - :query:`$rand`
360361

361-
- Generates a random number between 0 and 1.
362+
- Generates a random float between 0 and 1.
362363

363364
.. toctree::
364365
:titlesonly:
365366
:hidden:
366367

367-
/reference/operator/query-others
368+
/reference/operator/query-miscellaneous
368369

0 commit comments

Comments
 (0)