Skip to content

Commit 26eb453

Browse files
author
Dave
authored
DOCSP-21058 BACKPORT (#778)
1 parent 5ef9e25 commit 26eb453

File tree

1 file changed

+94
-14
lines changed
  • source/reference/operator/aggregation

1 file changed

+94
-14
lines changed

source/reference/operator/aggregation/first.txt

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,42 @@ value depends on the order of the documents coming into pipeline. To
3737
guarantee a defined order, the :pipeline:`$group` pipeline stage should
3838
follow a :pipeline:`$sort` stage.
3939

40-
Example
41-
-------
40+
.. include:: /includes/note-group-and-window-behavior.rst
4241

43-
Consider a ``sales`` collection with the following documents:
42+
Missing Values
43+
~~~~~~~~~~~~~~
44+
45+
The documents in a group may be missing fields or may have fields with
46+
missing values.
47+
48+
- If there are no documents from the prior pipeline stage, the
49+
:pipeline:`$group` stage returns nothing.
50+
- If the field that the :group:`$first` accumulator is processing is
51+
missing, :group:`$first` returns ``null``.
52+
53+
See the :ref:`missing data <first-missing-values-example>` example.
54+
55+
Examples
56+
--------
57+
58+
.. _first-accumulator-group-example:
59+
60+
Use in ``$group`` Stage
61+
~~~~~~~~~~~~~~~~~~~~~~~
62+
63+
Create the ``sales`` collection:
4464

4565
.. code-block:: javascript
4666

47-
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }
48-
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }
49-
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }
50-
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }
51-
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") }
52-
{ "_id" : 6, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-15T12:05:10Z") }
53-
{ "_id" : 7, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T14:12:12Z") }
67+
db.sales.insertMany( [
68+
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") },
69+
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") },
70+
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") },
71+
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") },
72+
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") },
73+
{ "_id" : 6, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-15T12:05:10Z") },
74+
{ "_id" : 7, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T14:12:12Z") }
75+
] )
5476

5577
Grouping the documents by the ``item`` field, the following operation
5678
uses the :group:`$first` accumulator to compute the first sales date for
@@ -65,7 +87,7 @@ each item:
6587
$group:
6688
{
6789
_id: "$item",
68-
firstSalesDate: { $first: "$date" }
90+
firstSale: { $first: "$date" }
6991
}
7092
}
7193
]
@@ -75,6 +97,64 @@ The operation returns the following results:
7597

7698
.. code-block:: javascript
7799

78-
{ "_id" : "xyz", "firstSalesDate" : ISODate("2014-02-03T09:05:00Z") }
79-
{ "_id" : "jkl", "firstSalesDate" : ISODate("2014-02-03T09:00:00Z") }
80-
{ "_id" : "abc", "firstSalesDate" : ISODate("2014-01-01T08:00:00Z") }
100+
[
101+
{ _id: 'jkl', firstSale: ISODate("2014-02-03T09:00:00.000Z") },
102+
{ _id: 'xyz', firstSale: ISODate("2014-02-03T09:05:00.000Z") },
103+
{ _id: 'abc', firstSale: ISODate("2014-01-01T08:00:00.000Z") }
104+
]
105+
106+
.. _first-missing-values-example:
107+
108+
Missing Data
109+
~~~~~~~~~~~~
110+
111+
Some documents in the ``badData`` collection are missing fields, other
112+
documents are missing values.
113+
114+
Create the ``badData`` collection:
115+
116+
.. code-block:: javascript
117+
118+
db.badData.insertMany( [
119+
{ "_id": 1, "price": 6, "quantity": 6 },
120+
{ "_id": 2, "item": "album", "price": 5 , "quantity": 5 },
121+
{ "_id": 7, "item": "tape", "price": 6, "quantity": 6 },
122+
{ "_id": 8, "price": 5, "quantity": 5 },
123+
{ "_id": 9, "item": "album", "price": 3, "quantity": '' },
124+
{ "_id": 10, "item": "tape", "price": 3, "quantity": 4 },
125+
{ "_id": 12, "item": "cd", "price": 7 }
126+
] )
127+
128+
Query the ``badData`` collection, grouping the output on the ``item``
129+
field:
130+
131+
.. code-block:: javascript
132+
133+
db.badData.aggregate( [
134+
{ $sort: { item: 1, price: 1 } },
135+
{ $group:
136+
{
137+
_id: "$item",
138+
inStock: { $first: "$quantity" }
139+
}
140+
}
141+
] )
142+
143+
The :pipeline:`$sort` stage orders the documents and passes them to the
144+
:pipeline:`$group` stage.
145+
146+
.. code-block:: javascript
147+
148+
[
149+
{ _id: null, inStock: 5 },
150+
{ _id: 'album', inStock: '' },
151+
{ _id: 'cd', inStock: null },
152+
{ _id: 'tape', inStock: 4 }
153+
]
154+
155+
:group:`$first` selects the first document from each output group:
156+
157+
- The ``_id: null`` group is included.
158+
- When the accumulator field, ``$quantity`` in this example, is
159+
missing, :group:`$first` returns ``null``.
160+

0 commit comments

Comments
 (0)