Skip to content

Commit 54a02bd

Browse files
author
Dave
authored
DOCSP-21058 first with empty pipeline (#766) (#777)
* DOCSP-21058 first with empty pipeline * Review feedback * Review feedback * Review feedback * Review feedback
1 parent 9b86a0b commit 54a02bd

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
@@ -48,20 +48,42 @@ value depends on the order of the documents coming into pipeline. To
4848
guarantee a defined order, the :pipeline:`$group` pipeline stage should
4949
follow a :pipeline:`$sort` stage.
5050

51-
Example
52-
-------
51+
.. include:: /includes/note-group-and-window-behavior.rst
5352

54-
Consider a ``sales`` collection with the following documents:
53+
Missing Values
54+
~~~~~~~~~~~~~~
55+
56+
The documents in a group may be missing fields or may have fields with
57+
missing values.
58+
59+
- If there are no documents from the prior pipeline stage, the
60+
:pipeline:`$group` stage returns nothing.
61+
- If the field that the :group:`$first` accumulator is processing is
62+
missing, :group:`$first` returns ``null``.
63+
64+
See the :ref:`missing data <first-missing-values-example>` example.
65+
66+
Examples
67+
--------
68+
69+
.. _first-accumulator-group-example:
70+
71+
Use in ``$group`` Stage
72+
~~~~~~~~~~~~~~~~~~~~~~~
73+
74+
Create the ``sales`` collection:
5575

5676
.. code-block:: javascript
5777

58-
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }
59-
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }
60-
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }
61-
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }
62-
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") }
63-
{ "_id" : 6, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-15T12:05:10Z") }
64-
{ "_id" : 7, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T14:12:12Z") }
78+
db.sales.insertMany( [
79+
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") },
80+
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") },
81+
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") },
82+
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") },
83+
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") },
84+
{ "_id" : 6, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-15T12:05:10Z") },
85+
{ "_id" : 7, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T14:12:12Z") }
86+
] )
6587

6688
Grouping the documents by the ``item`` field, the following operation
6789
uses the :group:`$first` accumulator to compute the first sales date for
@@ -76,7 +98,7 @@ each item:
7698
$group:
7799
{
78100
_id: "$item",
79-
firstSalesDate: { $first: "$date" }
101+
firstSale: { $first: "$date" }
80102
}
81103
}
82104
]
@@ -86,6 +108,64 @@ The operation returns the following results:
86108

87109
.. code-block:: javascript
88110

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

0 commit comments

Comments
 (0)