Add Secondary Indexes to Time Series Collections向时间序列集合添加辅助索引
On this page本页内容
To improve query performance for time series collections, add one or more secondary indexes to support common time series query patterns. 要提高时间序列集合的查询性能,请添加一个或多个辅助索引以支持常见的时间序列查询模式。Starting in MongoDB 6.3, MongoDB automatically creates a compound index on the 从MongoDB 6.3开始,MongoDB会自动在metaField
and timeField
fields for new collections.metaField
和timeField
字段上为新集合创建一个复合索引。
Not all index types are supported. For a list of unsupported index types, see Limitations for Secondary Indexes on Time Series Collections.并非所有索引类型都受支持。有关不受支持的索引类型的列表,请参阅时间序列集合上辅助索引的限制。
You may wish to create additional secondary indexes. Consider a weather data collection with the configuration:您可能希望创建其他辅助索引。考虑使用以下配置集合天气数据:
db.createCollection(
"weather",
{
timeseries: {
timeField: "timestamp",
metaField: "metadata"
}})
In each weather data document, the 在每个天气数据文档中,metadata
field value is a subdocument with fields for the weather sensor ID and type:metadata
字段值是一个子文档,其中包含天气传感器ID和类型的字段:
{
"timestamp": ISODate("2021-05-18T00:00:00.000Z"),
"metadata": {
"sensorId": 5578,
"type": "temperature"
},
"temp": 12
}
The default compound index for the collection indexes the entire 集合的默认复合索引对整个metadata
subdocument, so the index is only used with $eq
queries. metadata
子文档进行索引,因此该索引仅用于$eq
查询。By indexing specific 通过索引特定的metadata
fields, you improve query performance for other query types.metadata
字段,可以提高其他查询类型的查询性能。
For example, this 例如,此$in
query benefits from a secondary index on metadata.type
:$in
查询得益于元数据类型上的辅助索引:
{ metadata.type:{ $in: ["temperature", "pressure"] }}
See: 参阅:
Use Secondary Indexes to Improve Sort Performance使用辅助索引提高排序性能
Sort operations on time series collections can use secondary indexes on the 时间序列集合上的排序操作可以使用timeField
field. timeField
字段上的辅助索引。Under certain conditions, sort operations can also use compound secondary indexes on the 在某些条件下,排序操作还可以对metaField
and timeField
fields.metaField
和timeField
字段使用复合辅助索引。
The aggregation pipeline stages 聚合管道阶段$match
and $sort
determine which indexes a time series collection can use. $match
和$sort
决定时间序列集合可以使用哪些索引。An index can be used in the following scenarios:索引可用于以下场景:
Sort on在{ <timeField>: ±1 }
uses a secondary index on<timeField>
{ <timeField>: ±1 }
上排序在<timeField>
上使用辅助索引Sort on在{ <metaField>: ±1, timeField: ±1 }
uses the default compound index on{ <metaField>: ±1, timeField: ±1 }
{ <metaField>: ±1, timeField: ±1 }
上排序在{ <metaField>: ±1, timeField: ±1 }
上使用默认复合索引Sort on在{ <timeField>: ±1 }
uses a secondary index on{ metaField: ±1, timeField: ±1 }
when there is a point predicate on<metaField>
{ <timeField>: ±1 }
上排序在{ metaField: ±1, timeField: ±1 }
上使用辅助索引,当在<metaField>
上存在点谓语时
For example, the following 例如,以下sensorData
collection contains measurements from weather sensors:sensorData
集合包含来自天气传感器的测量值:
db.sensorData.insertMany( [ {
"metadata": {
"sensorId": 5578,
"type": "omni",
"location": {
type: "Point",
coordinates: [-77.40711, 39.03335]
}
},
"timestamp": ISODate("2022-01-15T00:00:00.000Z"),
"currentConditions": {
"windDirection": 127.0,
"tempF": 71.0,
"windSpeed": 2.0,
"cloudCover": null,
"precip": 0.1,
"humidity": 94.0,
}
},
{
"metadata": {
"sensorId": 5578,
"type": "omni",
"location": {
type: "Point",
coordinates: [-77.40711, 39.03335]
}
},
"timestamp": ISODate("2022-01-15T00:01:00.000Z"),
"currentConditions": {
"windDirection": 128.0,
"tempF": 69.8,
"windSpeed": 2.2,
"cloudCover": null,
"precip": 0.1,
"humidity": 94.3,
}
},
{
"metadata": {
"sensorId": 5579,
"type": "omni",
"location": {
type: "Point",
coordinates: [-80.19773, 25.77481]
}
},
"timestamp": ISODate("2022-01-15T00:01:00.000Z"),
"currentConditions": {
"windDirection": 115.0,
"tempF": 88.0,
"windSpeed": 1.0,
"cloudCover": null,
"precip": 0.0,
"humidity": 99.0,
}
}
]
)
Create a secondary single-field index on the 在timestamp
field:timestamp
字段上创建辅助单字段索引:
db.sensorData.createIndex( { "timestamp": 1 } )
The following sort operation on the 以下对timestamp
field uses the Secondary Index to improve performance:timestamp
字段的排序操作使用辅助索引来提高性能:
db.sensorData.aggregate( [
{ $match: { "timestamp" : { $gte: ISODate("2022-01-15T00:00:00.000Z") } } },
{ $sort: { "timestamp": 1 } }
] )
To confirm that the sort operation used the Secondary Index, run the operation again with the 要确认排序操作使用了辅助索引,请使用.explain( "executionStats" )
option:.explain( "executionStats" )
选项再次运行该操作:
db.sensorData.explain( "executionStats" ).aggregate( [
{ $match: { "timestamp": { $gte: ISODate("2022-01-15T00:00:00.000Z") } } },
{ $sort: { "timestamp": 1 } }
] )
Last Point Queries on Time Series Collections时间序列集合的最后一点查询
In time series data, a last point query returns the data point with the latest timestamp for a given field. 在时间序列数据中,最后一个点查询返回具有给定字段的最新时间戳的数据点。For time series collections, a last point query fetches the latest measurement for each unique metadata value. 对于时间序列集合,最后一点查询获取每个唯一元数据值的最新测量值。For example, you may want to get the latest temperature reading from all sensors. Improve performance on last point queries by creating any of the following indexes:例如,您可能想要从所有传感器获得最新的温度读数。通过创建以下任意索引来提高最后一点查询的性能:
{ "metadata.sensorId": 1, "timestamp": 1 }
{ "metadata.sensorId": 1, "timestamp": -1 }
{ "metadata.sensorId": -1, "timestamp": 1 }
{ "metadata.sensorId": -1, "timestamp": -1 }
Last point queries are most performant when they use the DISTINCT_SCAN optimization. This optimization is only available when an index on 最后一点查询在使用DISTINCT_SCAN优化时性能最高。此优化仅在timeField
is descending.timeField
上的索引递减时可用。
The following command creates a compound secondary index on 以下命令在metaField
(ascending) and timeField
(descending):metaField
(升序)和timeField
(降序)上创建复合辅助索引:
db.sensorData.createIndex( { "metadata.sensorId": 1, "timestamp": -1 } )
The following last point query example uses the descending 以下最后一个点查询示例使用上面创建的递减timeField
compound secondary index created above:timeField
复合辅助索引:
db.sensorData.aggregate( [
{
$sort: { "metadata.sensorId": 1, "timestamp": -1 }
},
{
$group: {
_id: "$metadata.sensorId",
ts: { $first: "$timestamp" },
temperatureF: { $first: "$currentConditions.tempF" }
}
}
] )
To confirm that the last point query used the secondary index, run the operation again using 要确认最后一个点查询使用了辅助索引,请使用.explain( "executionStats" )
:.explain( "executionStats" )
再次运行该操作:
db.getCollection( 'sensorData' ).explain( "executionStats" ).aggregate( [
{
$sort: { "metadata.sensorId": 1, "timestamp": -1 }
},
{
$group: {
_id: "$metadata.sensorId",
ts: { $first: "$timestamp" },
temperatureF: { $first: "$currentConditions.tempF" }
}
}
] )
The winningPlan.queryPlan.inputStage.stage
is DISTINCT_SCAN
, which indicates that the index was used. winningPlan.queryPlan.inputStage.stage
为DISTINCT_SCAN
,表示使用了索引。For more information on the explain plan output, see Explain Results.有关解释计划输出的更多信息,请参阅解释结果。
Specify Index Hints for Time Series Collections指定时间序列集合的索引提示
Index hints cause MongoDB to use a specific index for a query. Some operations on time series collections can only take advantage of an index if that index is specified in a hint.索引提示导致MongoDB对查询使用特定的索引。只有在提示中指定了索引的情况下,时间序列集合上的某些操作才能利用该索引。
For example, the following query causes MongoDB to use the 例如,以下查询导致MongoDB使用timestamp_1_metadata.sensorId_1
index:timestamp_1_metadata.sensorId_1
索引:
db.sensorData.find( { "metadata.sensorId": 5578 } ).hint( "timestamp_1_metadata.sensorId_1" )
On a time series collection, you can specify hints using either the index name or the index key pattern. 在时间序列集合上,可以使用索引名称或索引键模式指定提示。To get the names of the indexes on a collection, use the 要获取集合上索引的名称,请使用db.collection.getIndexes()
method.db.collection.getIndexes()
方法。
Time Series Secondary Indexes in MongoDB 6.0 and LaterMongoDB 6.0及更高版本中的时间序列辅助索引
New in version 6.3. 6.3版新增。
Starting in MongoDB 6.3, you can create a partial TTL index for a time series collection. You can only filter on the 从MongoDB 6.3开始,您可以为时间序列集合创建部分TTL索引。您只能在metaField
.metaField
上进行筛选。
If the collection doesn't use the 如果集合不使用expireAfterSeconds
option to expire documents, creating a partial TTL index sets an expiration time for matching documents only. expireAfterSeconds
选项使文档过期,则创建部分TTL索引将仅为匹配的文档设置过期时间。If the collection uses 如果集合对所有文档使用expireAfterSeconds
for all documents, a partial TTL index lets you expire matching documents sooner.expireAfterSeconds
,则部分TTL索引可以使匹配的文档提前过期。
New in version 6.0. 6.0版新增。
Starting in MongoDB 6.0, you can:从MongoDB 6.0开始,您可以:
Add a compound index on the在timeField
,metaField
, or measurement fields.timeField
、metaField
或度量字段上添加复合索引。Use the对时间序列集合使用带有部分索引的$or
,$in
, and$geoWithin
operators with partial indexes on a time series collection.$or
、$in
和$geoWithin
运算符。Add a partial filter expression on the在metaField
.metaField
上添加部分筛选器表达式。Add a secondary index to any field or subfield.向任何字段或子字段添加辅助索引。Use the将metaField
with 2dsphere indexes.metaField
与2dsphere
索引一起使用。
If there are secondary indexes on time series collections and you need to downgrade the feature compatibility version (FCV), you must first drop any secondary indexes that are incompatible with the downgraded FCV. 如果时间序列集合上有辅助索引,并且需要降级功能兼容性版本(FCV),则必须首先删除与降级的FCV不兼容的所有辅助索引。See 请参阅setFeatureCompatibilityVersion
.setFeatureCompatibilityVersion
。