Skip to content

Commit 538d413

Browse files
author
Dave
authored
DOCSP-21058 first with empty pipeline (#766)
* DOCSP-21058 first with empty pipeline * Review feedback * Review feedback * Review feedback * Review feedback
1 parent ffc313d commit 538d413

File tree

1 file changed

+84
-12
lines changed
  • source/reference/operator/aggregation

1 file changed

+84
-12
lines changed

source/reference/operator/aggregation/first.txt

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,19 @@ Behavior
4747

4848
.. include:: /includes/note-group-and-window-behavior.rst
4949

50+
Missing Values
51+
~~~~~~~~~~~~~~
52+
53+
The documents in a group may be missing fields or may have fields with
54+
missing values.
55+
56+
- If there are no documents from the prior pipeline stage, the
57+
:pipeline:`$group` stage returns nothing.
58+
- If the field that the :group:`$first` accumulator is processing is
59+
missing, :group:`$first` returns ``null``.
60+
61+
See the :ref:`missing data <first-missing-values-example>` example.
62+
5063
Examples
5164
--------
5265

@@ -55,17 +68,19 @@ Examples
5568
Use in ``$group`` Stage
5669
~~~~~~~~~~~~~~~~~~~~~~~
5770

58-
Consider a ``sales`` collection with the following documents:
71+
Create the ``sales`` collection:
5972

6073
.. code-block:: javascript
6174

62-
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }
63-
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }
64-
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }
65-
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }
66-
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") }
67-
{ "_id" : 6, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-15T12:05:10Z") }
68-
{ "_id" : 7, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T14:12:12Z") }
75+
db.sales.insertMany( [
76+
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") },
77+
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") },
78+
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") },
79+
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") },
80+
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") },
81+
{ "_id" : 6, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-15T12:05:10Z") },
82+
{ "_id" : 7, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T14:12:12Z") }
83+
] )
6984

7085
Grouping the documents by the ``item`` field, the following operation
7186
uses the :group:`$first` accumulator to compute the first sales date for
@@ -80,7 +95,7 @@ each item:
8095
$group:
8196
{
8297
_id: "$item",
83-
firstSalesDate: { $first: "$date" }
98+
firstSale: { $first: "$date" }
8499
}
85100
}
86101
]
@@ -90,9 +105,66 @@ The operation returns the following results:
90105

91106
.. code-block:: javascript
92107

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

97169
.. _first-accumulator-window-example:
98170

0 commit comments

Comments
 (0)