Skip to content

Commit b712883

Browse files
ianf-mongodbjeff-allen-mongo
authored andcommitted
Docsp 19835 document top bottom (#154)
* DOCSP-19835 * * * ** * adjustment from feedback 1 * rearrange aggregation.txt * * * address changes 2 * tweeks * Address Mihai suggestions #1 * Add note for more deterministic tie breaking * Adding PlayerD is returned bullet top top page * Address null and missing value verbiage
1 parent c771a41 commit b712883

File tree

6 files changed

+574
-4
lines changed

6 files changed

+574
-4
lines changed

source/includes/extracts-agg-operators.yaml

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,16 @@ content: |
10201020
10211021
Available in :pipeline:`$setWindowFields` stage.
10221022
1023+
* - :group:`$bottom`
1024+
1025+
- Returns the bottom element within a group according to the specified
1026+
sort order.
1027+
1028+
.. versionadded:: 5.2
1029+
1030+
Available in :pipeline:`$group` and
1031+
:pipeline:`$setWindowFields` stages.
1032+
10231033
* - :group:`$bottomN`
10241034
10251035
- Returns an aggregation of the bottom ``n`` fields within a group,
@@ -1117,6 +1127,16 @@ content: |
11171127
11181128
Available in :pipeline:`$setWindowFields` stage.
11191129
1130+
* - :group:`$top`
1131+
1132+
- Returns the top element within a group according to the specified
1133+
sort order.
1134+
1135+
.. versionadded:: 5.2
1136+
1137+
Available in :pipeline:`$group` and
1138+
:pipeline:`$setWindowFields` stages.
1139+
11201140
* - :group:`$topN`
11211141
11221142
- Returns an aggregation of the top ``n`` fields within a group,
@@ -1212,6 +1232,16 @@ content: |
12121232
12131233
Available in :pipeline:`$setWindowFields` stage.
12141234
1235+
* - :group:`$bottom`
1236+
1237+
- Returns the bottom element within a group according to the specified
1238+
sort order.
1239+
1240+
.. versionadded:: 5.2
1241+
1242+
Available in :pipeline:`$group` and
1243+
:pipeline:`$setWindowFields` stages.
1244+
12151245
* - :group:`$bottomN`
12161246
12171247
- Returns an aggregation of the bottom ``n`` fields within a group,
@@ -1383,7 +1413,17 @@ content: |
13831413
.. versionchanged:: 5.0
13841414
13851415
Available in :pipeline:`$setWindowFields` stage.
1386-
1416+
1417+
* - :group:`$top`
1418+
1419+
- Returns the top element within a group according to the specified
1420+
sort order.
1421+
1422+
.. versionadded:: 5.2
1423+
1424+
Available in :pipeline:`$group` and
1425+
:pipeline:`$setWindowFields` stages.
1426+
13871427
* - :group:`$topN`
13881428
13891429
- Returns an aggregation of the top ``n`` fields within a group,

source/includes/setWindowFields-operators.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ These operators can be used with the :pipeline:`$setWindowFields` stage:
33
.. _setWindowFields-accumulator-operators:
44

55
- Accumulator operators: :group:`$addToSet`, :group:`$avg`,
6-
:group:`$bottomN`, :group:`$count`, :group:`$covariancePop`,
7-
:group:`$covarianceSamp`, :group:`$derivative`,
6+
:group:`$bottom`, :group:`$bottomN`, :group:`$count`,
7+
:group:`$covariancePop`, :group:`$covarianceSamp`, :group:`$derivative`,
88
:group:`$expMovingAvg`, :group:`$integral`, :group:`$max`,
99
:group:`$min`, :group:`$push`, :group:`$stdDevSamp`,
10-
:group:`$stdDevPop`, :group:`$sum` and :group:`$topN`.
10+
:group:`$stdDevPop`, :group:`$sum`, :group:`$top`
11+
and :group:`$topN`.
1112

1213
.. _setWindowFields-gap-filling-operators:
1314

source/reference/operator/aggregation.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,16 @@ Alphabetical Listing of Expression Operators
265265

266266
.. versionadded:: 4.4
267267

268+
* - :group:`$bottom`
269+
270+
- Returns the bottom element within a group according to the specified
271+
sort order.
272+
273+
.. versionadded:: 5.2
274+
275+
Available in :pipeline:`$group` and
276+
:pipeline:`$setWindowFields` stages.
277+
268278
* - :group:`$bottomN`
269279

270280
- Returns an aggregation of the bottom ``n`` fields within a group,
@@ -1108,6 +1118,16 @@ Alphabetical Listing of Expression Operators
11081118
- Converts value to an ObjectId.
11091119

11101120

1121+
* - :group:`$top`
1122+
1123+
- Returns the top element within a group according to the specified
1124+
sort order.
1125+
1126+
.. versionadded:: 5.2
1127+
1128+
Available in :pipeline:`$group` and
1129+
:pipeline:`$setWindowFields` stages.
1130+
11111131
* - :group:`$topN`
11121132

11131133
- Returns an aggregation of the top ``n`` fields within a group,
@@ -1211,6 +1231,7 @@ Alphabetical Listing of Expression Operators
12111231
/reference/operator/aggregation/atanh
12121232
/reference/operator/aggregation/avg
12131233
/reference/operator/aggregation/binarySize
1234+
/reference/operator/aggregation/bottom
12141235
/reference/operator/aggregation/bsonSize
12151236
/reference/operator/aggregation/ceil
12161237
/reference/operator/aggregation/cmp
@@ -1340,6 +1361,7 @@ Alphabetical Listing of Expression Operators
13401361
/reference/operator/aggregation/toInt
13411362
/reference/operator/aggregation/toLong
13421363
/reference/operator/aggregation/toObjectId
1364+
/reference/operator/aggregation/top
13431365
/reference/operator/aggregation/toString
13441366
/reference/operator/aggregation/toLower
13451367
/reference/operator/aggregation/toUpper
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
=================================
2+
$bottom (aggregation accumulator)
3+
=================================
4+
5+
.. default-domain:: mongodb
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 1
11+
:class: singlecol
12+
13+
Definition
14+
----------
15+
16+
.. group:: $bottom
17+
18+
.. versionadded:: 5.2
19+
20+
Returns the bottom element within a group according to the specified
21+
sort order.
22+
23+
Syntax
24+
------
25+
26+
.. code-block:: none
27+
:copyable: false
28+
29+
{
30+
$bottom:
31+
{
32+
sortBy: { <field1>: <sort order>, <field2>: <sort order> ... },
33+
output: <expression>
34+
}
35+
}
36+
37+
.. list-table::
38+
:header-rows: 1
39+
:widths: 15 15 70
40+
41+
* - Field
42+
- Necessity
43+
- Description
44+
45+
* - sortBy
46+
47+
- Required
48+
49+
- Specifies the order of results, with syntax similar to
50+
:pipeline:`$sort`.
51+
52+
* - output
53+
54+
- Required
55+
56+
- Represents the output for each element in the group
57+
and can be any expression.
58+
59+
Behavior
60+
--------
61+
62+
Null and Missing Values
63+
~~~~~~~~~~~~~~~~~~~~~~~
64+
65+
Consider the following aggregation that returns the bottom
66+
document from a group of scores:
67+
68+
- ``$bottom`` does not filter out null values.
69+
- ``$bottom`` converts missing values to null.
70+
71+
.. code-block:: javascript
72+
:emphasize-lines: 7,8
73+
74+
db.aggregate( [
75+
{
76+
$documents: [
77+
{ playerId: "PlayerA", gameId: "G1", score: 1 },
78+
{ playerId: "PlayerB", gameId: "G1", score: 2 },
79+
{ playerId: "PlayerC", gameId: "G1", score: 3 },
80+
{ playerId: "PlayerD", gameId: "G1"},
81+
{ playerId: "PlayerE", gameId: "G1", score: null }
82+
]
83+
},
84+
{
85+
$group:
86+
{
87+
_id: "$gameId",
88+
playerId:
89+
{
90+
$bottom:
91+
{
92+
output: [ "$playerId", "$score" ],
93+
sortBy: { "score": -1 }
94+
}
95+
}
96+
}
97+
}
98+
] )
99+
100+
In this example:
101+
102+
- :pipeline:`$documents` creates the literal documents that contain
103+
player scores.
104+
- :pipeline:`$group` groups the documents by ``gameId``. This
105+
example has only one ``gameId``, ``G1``.
106+
- ``PlayerD`` has a missing score and ``PlayerE`` has a
107+
null ``score``. These values are both considered as null.
108+
- The ``playerId`` and ``score`` fields are specified as
109+
``output : ["$playerId"," $score"]`` and returned as array values.
110+
- Specify the sort order with ``sortBy: { "score": -1 }``.
111+
- ``PlayerD`` and ``PlayerE`` tied for the bottom element. ``PlayerD``
112+
is returned as the bottom ``score``.
113+
- To have more deterministic tie breaking behavior for multiple null
114+
values, add more fields to``sortBy``.
115+
116+
.. code-block:: javascript
117+
:copyable: false
118+
119+
[
120+
{
121+
_id: 'G1',
122+
playerId: [ [ 'PlayerD', null ] ]
123+
}
124+
]
125+
126+
Restrictions
127+
------------
128+
129+
Window Function and Aggregation Expression Support
130+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
131+
132+
``$bottom`` is not supported as a
133+
:ref:`aggregation expression <aggregation-expressions>`.
134+
135+
``$bottom`` is supported as a
136+
:pipeline:`window operator <$setWindowFields>`.
137+
138+
Memory Limit Considerations
139+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
140+
141+
Aggregation pipelines which call ``$bottom`` are subject to the
142+
:ref:`100 MB limit <agg-memory-restrictions>`. If this
143+
limit is exceeded for an individual group, the aggregation fails
144+
with an error.
145+
146+
Examples
147+
--------
148+
149+
Consider a ``gamescores`` collection with the following documents:
150+
151+
.. code-block:: javascript
152+
153+
db.gamescores.insertMany([
154+
{ playerId: "PlayerA", gameId: "G1", score: 31 },
155+
{ playerId: "PlayerB", gameId: "G1", score: 33 },
156+
{ playerId: "PlayerC", gameId: "G1", score: 99 },
157+
{ playerId: "PlayerD", gameId: "G1", score: 1 },
158+
{ playerId: "PlayerA", gameId: "G2", score: 10 },
159+
{ playerId: "PlayerB", gameId: "G2", score: 14 },
160+
{ playerId: "PlayerC", gameId: "G2", score: 66 },
161+
{ playerId: "PlayerD", gameId: "G2", score: 80 }
162+
])
163+
164+
Find the Bottom ``Score``
165+
~~~~~~~~~~~~~~~~~~~~~~~~~
166+
167+
You can use the ``$bottom`` accumulator to find the bottom score in a
168+
single game.
169+
170+
.. code-block:: javascript
171+
172+
db.gamescores.aggregate( [
173+
{
174+
$match : { gameId : "G1" }
175+
},
176+
{
177+
$group:
178+
{
179+
_id: "$gameId",
180+
playerId:
181+
{
182+
$bottom:
183+
{
184+
output: [ "$playerId", "$score" ],
185+
sortBy: { "score": -1 }
186+
}
187+
}
188+
}
189+
}
190+
] )
191+
192+
The example pipeline:
193+
194+
- Uses :pipeline:`$match` to filter the results on a single ``gameId``.
195+
In this case, ``G1``.
196+
- Uses :pipeline:`$group` to group the results by ``gameId``. In this
197+
case, ``G1``.
198+
- Specifies the fields that are output for ``$bottom`` with
199+
``output : ["$playerId"," $score"]``.
200+
- Uses ``sortBy: { "score": -1 }`` to sort the scores in descending order.
201+
- Uses ``$bottom`` to return the bottom score for the game.
202+
203+
The operation returns the following results:
204+
205+
.. code-block:: javascript
206+
:copyable: false
207+
208+
[ { _id: 'G1', playerId: [ 'PlayerD', 1 ] } ]
209+
210+
Finding the Bottom ``Score`` Across Multiple Games
211+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
212+
213+
You can use the ``$bottom`` accumulator to find the bottom ``score``
214+
in each game.
215+
216+
.. code-block:: javascript
217+
218+
db.gamescores.aggregate( [
219+
{
220+
$group:
221+
{ _id: "$gameId", playerId:
222+
{
223+
$bottom:
224+
{
225+
output: [ "$playerId", "$score" ],
226+
sortBy: { "score": -1 }
227+
}
228+
}
229+
}
230+
}
231+
] )
232+
233+
The example pipeline:
234+
235+
- Uses ``$group`` to group the results by ``gameId``.
236+
- Uses ``$bottom`` to return the bottom ``score`` for each game.
237+
- Specifies the fields that are output for ``$bottom`` with
238+
``output : ["$playerId", "$score"]``.
239+
- Uses ``sortBy: { "score": -1 }`` to sort the scores in descending order.
240+
241+
The operation returns the following results:
242+
243+
.. code-block:: javascript
244+
:copyable: false
245+
246+
[
247+
{ _id: 'G2', playerId: [ 'PlayerA', 10 ] },
248+
{ _id: 'G1', playerId: [ 'PlayerD', 1 ] }
249+
]

0 commit comments

Comments
 (0)