Database Manual / Time Series / Indexes

Add Secondary Indexes to Time Series Collections向时间序列集合添加二级索引

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 metaField and timeField fields for new collections.从MongoDB 6.3开始,MongoDB会自动在metaFieldtimeField字段上为新集合创建复合索引

Note

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. By indexing specific metadata fields, you improve query performance for other query types.集合的默认复合索引对整个metadata子文档进行索引,因此该索引仅用于$eq查询。通过索引特定的metadata字段,可以提高其他查询类型的查询性能。

For example, this $in query benefits from a secondary index on metadata.type:例如,此$in查询受益于元数据类型的辅助索引:

{ metadata.type:{ $in: ["temperature", "pressure"] }}

Use Secondary Indexes to Improve Sort Performance使用辅助索引提高排序性能

Sort operations on time series collections can use secondary indexes on the timeField field. Under certain conditions, sort operations can also use compound secondary indexes on the metaField and timeField fields.对时间序列集合的排序操作可以在timeField字段上使用辅助索引。在某些条件下,排序操作还可以在metaFieldtimeField字段上使用复合二级索引。

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>上使用二级索引
  • Sort on { <metaField>: ±1, timeField: ±1 } uses the default compound index on { <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><metaField>上有一个点谓词时,对{ <timeField>: ±1 }进行排序会在{ metaField: ±1, timeField: ±1 }上使用二级索引

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 }

Note

Last point queries are most performant when they use the DISTINCT_SCAN optimization. This optimization is only available when an index on timeField is descending.当使用DISTINCT_SCAN优化时,最后一点查询的性能最高。此优化仅在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. For more information on the explain plan output, see Explain Results.winningPlan.queryPlan.inputStage.stage阶段为DISTINCT_SCAN,表示使用了索引。有关解释计划输出的更多信息,请参阅解释结果

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 timestamp_1_metadata.sensorId_1 index:例如,以下查询导致MongoDB使用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()方法。

Create 2dsphere Indexes创建2dsphere索引

Starting in version 6.0 you can create 2dsphere indexes on the timeField, metaField, or measurement fields.从6.0版本开始,您可以在timeFieldmetaField或度量字段上创建2dsphere索引。

For example, the following operation creates a 2dsphere index on the location field:例如,以下操作在location字段上创建2dsphere索引:

Example示例

db.sensorData.createIndex({ "metadata.location": "2dsphere" })

Additionally, the following operation creates a 2dsphere index on measurement fields:此外,以下操作在测量字段上创建2dsphere索引:

Example示例

db.sensorData.createIndex({ "currentConditions.tempF": "2dsphere" })

Note

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不兼容的任何辅助索引。For more information, see setFeatureCompatibilityVersion.有关更多信息,请参阅setFeatureCompatibilityVersion