@@ -18,26 +18,55 @@ Add Secondary Indexes to Time Series Collections
18
18
19
19
To improve query performance for :term:`time series collections <time
20
20
series collection>`, add one or more :term:`secondary indexes <secondary
21
- index>` to support common time series query patterns. Specifically, we
22
- recommend that you create one or more :ref:`compound indexes
23
- <index-type-compound>` on the fields specified as the ``timeField`` and
24
- the ``metaField``. If the field value for the ``metaField`` field is a
25
- document, you can create secondary indexes on fields inside that
26
- document.
21
+ index>` to support common time series query patterns. Starting in
22
+ MongoDB 6.3, MongoDB automatically creates a :ref:`compound index
23
+ <index-type-compound>` on the ``metaField`` and ``timeField`` fields for
24
+ new collections.
27
25
28
26
.. note::
29
27
30
28
Not all index types are supported. For a list of unsupported index
31
29
types, see :ref:`Limitations for Secondary Indexes on Time Series
32
30
Collections <timeseries-limitations-secondary-indexes>`.
33
31
34
- For example, this command creates a :ref:`compound index
35
- <index-type-compound>` on the ``metadata.sensorId`` and ``timestamp``
36
- fields:
32
+ You may wish to create additional secondary indexes. Consider a weather
33
+ data collection with the configuration:
37
34
38
35
.. code-block:: javascript
39
36
40
- db.weather24h.createIndex( { "metadata.sensorId": 1, "timestamp": 1 } )
37
+ db.createCollection(
38
+ "weather",
39
+ {
40
+ timeseries: {
41
+ timeField: "timestamp",
42
+ metaField: "metadata"
43
+ }})
44
+
45
+ In each weather data document, the ``metadata`` field value is a
46
+ subdocument with fields for the weather sensor ID and type:
47
+
48
+ .. code-block:: javascript
49
+
50
+ {
51
+ "timestamp": ISODate("2021-05-18T00:00:00.000Z"),
52
+ "metadata": {
53
+ "sensorId": 5578,
54
+ "type": "temperature"
55
+ },
56
+ "temp": 12
57
+ }
58
+
59
+ The default compound index for the collection indexes the entire
60
+ ``metadata`` subdocument, so the index is only used with
61
+ :expression:`$eq` queries. By indexing specific ``metadata`` fields, you
62
+ improve query performance for other query types.
63
+
64
+ For example, this :expression:`$in` query benefits from a
65
+ secondary index on ``metadata.type``:
66
+
67
+ .. code-block:: javascript
68
+
69
+ { metadata.type:{ $in: ["temperature", "pressure"] }}
41
70
42
71
.. see::
43
72
@@ -48,9 +77,22 @@ fields:
48
77
Use Secondary Indexes to Improve Sort Performance
49
78
-------------------------------------------------
50
79
51
- Time Series collections can use indexes to improve sort performance on
52
- the ``timeField`` and the ``metaField``.
53
-
80
+ Sort operations on time series collections can use secondary indexes
81
+ on the ``timeField`` field. Under certain conditions, sort operations can also use compound secondary indexes on the ``metaField`` and
82
+ ``timeField`` fields.
83
+
84
+ The aggregation pipeline stages :pipeline:`$match` and
85
+ :pipeline:`$sort` determine which indexes a time series collection can
86
+ use. An index can be used in the following scenarios:
87
+
88
+ - Sort on ``{ <timeField>: ±1 }`` uses a secondary index on
89
+ ``<timeField>``
90
+ - Sort on ``{ <metaField>: ±1, timeField: ±1 }`` uses the default
91
+ compound index on ``{ <metaField>: ±1, timeField: ±1 }``
92
+ - Sort on ``{ <timeField>: ±1 }`` uses a secondary index on
93
+ ``{ metaField: ±1, timeField: ±1 }`` when there is a point predicate
94
+ on ``<metaField>``
95
+
54
96
For example, the following ``sensorData`` collection contains
55
97
measurements from weather sensors:
56
98
@@ -59,14 +101,15 @@ measurements from weather sensors:
59
101
db.sensorData.insertMany( [ {
60
102
"metadata": {
61
103
"sensorId": 5578,
104
+ "type": "omni",
62
105
"location": {
63
106
type: "Point",
64
107
coordinates: [-77.40711, 39.03335]
65
108
}
66
109
},
67
110
"timestamp": ISODate("2022-01-15T00:00:00.000Z"),
68
111
"currentConditions": {
69
- "windDirecton ": 127.0,
112
+ "windDirection ": 127.0,
70
113
"tempF": 71.0,
71
114
"windSpeed": 2.0,
72
115
"cloudCover": null,
@@ -77,14 +120,15 @@ measurements from weather sensors:
77
120
{
78
121
"metadata": {
79
122
"sensorId": 5578,
123
+ "type": "omni",
80
124
"location": {
81
125
type: "Point",
82
126
coordinates: [-77.40711, 39.03335]
83
127
}
84
128
},
85
129
"timestamp": ISODate("2022-01-15T00:01:00.000Z"),
86
130
"currentConditions": {
87
- "windDirecton ": 128.0,
131
+ "windDirection ": 128.0,
88
132
"tempF": 69.8,
89
133
"windSpeed": 2.2,
90
134
"cloudCover": null,
@@ -95,14 +139,15 @@ measurements from weather sensors:
95
139
{
96
140
"metadata": {
97
141
"sensorId": 5579,
142
+ "type": "omni",
98
143
"location": {
99
144
type: "Point",
100
145
coordinates: [-80.19773, 25.77481]
101
146
}
102
147
},
103
148
"timestamp": ISODate("2022-01-15T00:01:00.000Z"),
104
149
"currentConditions": {
105
- "windDirecton ": 115.0,
150
+ "windDirection ": 115.0,
106
151
"tempF": 88.0,
107
152
"windSpeed": 1.0,
108
153
"cloudCover": null,
@@ -113,62 +158,7 @@ measurements from weather sensors:
113
158
]
114
159
)
115
160
116
- Time Series collections :ref:automatically create an internal
117
- :ref:`clustered index <db.createCollection.clusteredIndex>`. The query
118
- planner uses this index to improve sort performance.
119
-
120
- .. note::
121
- If you insert a document into a collection with a ``timeField``
122
- value before ``1970-01-01T00:00:00.000Z`` or after
123
- ``2038-01-19T03:14:07.000Z``,
124
- MongoDB logs a warning and prevents some query optimizations from
125
- using the internal index. :ref:`Create a secondary index <timeseries-add-secondary-index>`
126
- on the ``timeField`` to regain query performance and resolve the log
127
- warning.
128
-
129
- The following sort operation on the ``timestamp`` field uses the
130
- clustered index to improve performance:
131
-
132
- .. code-block:: javascript
133
-
134
- db.sensorData.find().sort( { "timestamp": 1 } )
135
-
136
- To confirm that the sort operation used the clustered index, run the
137
- operation again with the ``.explain( "executionStats" )`` option:
138
-
139
- .. code-block:: javascript
140
-
141
- db.sensorData.find().sort( { "timestamp": 1 } ).explain( "executionStats" )
142
-
143
- The ``winningPlan.queryPlan.inputStage.stage`` is ``COLLSCAN`` and an
144
- ``_internalBoundedSort`` stage is present in the explain plan output.
145
- The ``interalBoundedSort`` field indicates that the clustered index was
146
- used. For more information on explain plan output, see :ref:`explain
147
- results <explain-results>`.
148
-
149
- Secondary indexes on Time Series collections can improve
150
- performance for sort operations and increase the number of scenarios
151
- where indexes can be used.
152
-
153
- Sort operations on Time Series collections can use secondary indexes
154
- on the ``timeField``. Under certain conditions, sort operations can
155
- also use compound secondary indexes on the ``metaField`` and
156
- ``timeField``.
157
-
158
- The Aggregation Pipeline Stages :pipeline:`$match` and
159
- :pipeline:`$sort` determine which indexes a Time Series collection can
160
- use. The following list describes scenarios where an index can be used:
161
-
162
- - Sort on ``{ <timeField:> ±1 }`` uses the clustered index
163
- - Sort on ``{ <timeField>: ±1 }`` uses a secondary index on
164
- ``<timeField>``
165
- - Sort on ``{ <metaField>: ±1, timeField: ±1 }`` uses a secondary
166
- index on ``{ <metaField>: ±1, timeField: ±1 }``
167
- - Sort on ``{ <timeField>: ±1 }`` uses a secondary index on
168
- ``{ metaField: ±1, timeField: ±1 }`` when there is a point predicate
169
- on ``<metaField>``
170
-
171
- Create a secondary index on the ``timestamp`` field:
161
+ Create a secondary single-field index on the ``timestamp`` field:
172
162
173
163
.. code-block:: javascript
174
164
@@ -195,13 +185,15 @@ operation again with the ``.explain( "executionStats" )`` option:
195
185
] )
196
186
197
187
198
- " Last Point" Queries on Time Series Collections
188
+ Last Point Queries on Time Series Collections
199
189
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
200
190
201
- A "last point" query fetches the latest measurement for each unique metadata
202
- value. For example, you may want to get the latest temperature reading from all
203
- sensors. Improve performance on last point queries by creating any of the
204
- following indexes:
191
+ In time series data, a last point query returns the data point with the
192
+ latest timestamp for a given field. For time series collections, a last
193
+ point query fetches the latest measurement for each unique metadata
194
+ value. For example, you may want to get the latest temperature reading
195
+ from all sensors. Improve performance on last point queries by creating
196
+ any of the following indexes:
205
197
206
198
.. code-block:: javascript
207
199
@@ -283,19 +275,32 @@ a collection, use the :method:`db.collection.getIndexes()` method.
283
275
284
276
.. _timeseries-add-secondary-index-mongodb-6.0:
285
277
286
- Time Series Secondary Indexes in MongoDB 6.0
287
- --------------------------------------------
278
+ Time Series Secondary Indexes in MongoDB 6.0 and Later
279
+ ------------------------------------------------------
280
+
281
+ .. versionadded:: 6.3
282
+
283
+ Starting in MongoDB 6.3, you can create a partial :ref:`TTL
284
+ index<index-feature-ttl>` for a time series collection. You can only
285
+ filter on the ``metaField``.
286
+
287
+ If the collection doesn't use the ``expireAfterSeconds`` option to
288
+ expire documents, creating a partial TTL index sets an
289
+ expiration time for matching documents only. If the collection uses
290
+ ``expireAfterSeconds`` for all documents, a partial TTL index lets you expire matching documents sooner.
291
+
292
+ .. versionadded:: 6.0
288
293
289
294
Starting in MongoDB 6.0, you can:
290
295
291
296
- Add a :ref:`compound index <index-type-compound>` on the
292
297
``timeField``, ``metaField``, or measurement fields.
293
298
294
299
- Use the :query:`$or`, :query:`$in`, and :query:`$geoWithin` operators
295
- with :doc :`partial indexes </core/ index-partial>` on a time series
300
+ with :ref :`partial indexes <index-type -partial>` on a time series
296
301
collection.
297
302
298
- - Add :doc:`partial </core/index- partial>` on the ``metaField``.
303
+ - Add a partial filter expression on the ``metaField``.
299
304
300
305
- Add a :term:`secondary index <secondary index>` to any field or
301
306
subfield.
0 commit comments