@@ -48,8 +48,8 @@ fields:
48
48
Use Secondary Indexes to Improve Sort Performance
49
49
-------------------------------------------------
50
50
51
- Sort operations on the ``timeField`` and ``metaField`` can use secondary
52
- indexes on those fields to improve performance.
51
+ Create secondary indexes on the ``timeField`` and ``metaField`` fields to
52
+ improve sort performance.
53
53
54
54
For example, the following ``sensorData`` collection contains
55
55
temperature readings:
@@ -101,6 +101,74 @@ The ``winningPlan.queryPlan.inputStage.stage`` is ``IXSCAN``, which
101
101
indicates that the index was used. For more information on explain plan
102
102
output, see :ref:`explain-results`.
103
103
104
+ "Last Point" Queries on Time Series Collections
105
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
106
+
107
+ A "last point" query fetches the latest measurement for each unique metadata
108
+ value. For example, you may want to get the latest temperature reading from all
109
+ sensors. Improve performance on last point queries by creating any of the
110
+ following indexes:
111
+
112
+ .. code-block:: javascript
113
+
114
+ { "metadata.sensorId": 1, "timestamp": 1 }
115
+ { "metadata.sensorId": 1, "timestamp": -1 }
116
+ { "metadata.sensorId": -1, "timestamp": 1 }
117
+ { "metadata.sensorId": -1, "timestamp": -1 }
118
+
119
+ .. note::
120
+
121
+ Last point queries are most performant when they use the :ref:`DISTINCT_SCAN
122
+ optimization <explain-results>`. This optimization is only available when an
123
+ index on ``timeField`` is descending.
124
+
125
+ The following command creates a compound secondary index on ``metaField``
126
+ (ascending) and ``timeField`` (descending):
127
+
128
+ .. code-block:: javascript
129
+
130
+ db.sensorData.createIndex( { "metadata.sensorId": 1, "timestamp": -1 } )
131
+
132
+ The following last point query example uses the descending ``timeField``
133
+ compound secondary index created above:
134
+
135
+ .. code-block:: javascript
136
+
137
+ db.sensorData.aggregate( [
138
+ {
139
+ $sort: { "metadata.sensorId": 1, "timestamp": -1 }
140
+ },
141
+ {
142
+ $group: {
143
+ _id: "$metadata.sensorId",
144
+ ts: { $first: "$timestamp" },
145
+ temperatureF: { $first: "$currentConditions.tempF" }
146
+ }
147
+ }
148
+ ] )
149
+
150
+ To confirm that the last point query used the secondary index, run the operation
151
+ again using ``.explain("executionStats")``:
152
+
153
+ .. code-block:: javascript
154
+
155
+ db.getCollection('sensorData').explain("executionStats").aggregate( [
156
+ {
157
+ $sort: { "metadata.sensorId": 1, "timestamp": -1 }
158
+ },
159
+ {
160
+ $group: {
161
+ _id: "$metadata.sensorId",
162
+ ts: {$first: "$timestamp"},
163
+ temperatureF: {$first: "$currentConditions.tempF" }
164
+ }
165
+ }
166
+ ] )
167
+
168
+ The ``winningPlan.queryPlan.inputStage.stage`` is ``DISTINCT_SCAN``, which
169
+ indicates that the index was used. For more information on the explain plan
170
+ output, see :ref:`explain-results`.
171
+
104
172
Specify Index Hints for Time Series Collections
105
173
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
106
174
0 commit comments