时间序列集合注意事项
时间序列集合的行为通常与普通集合类似,但也有例外情况。有关时间序列集合行为和结构的信息,请参阅 时间序列集合。
metaField 注意事项
metaField
应该很少改变,可以是任何数据类型。metaField
可以是一个对象,可以包含子字段。将字段定义为 metaField
后,可以更改 metaField
的值,但不能将 metaField
重新定义为另一个字段。例如,如果创建时间序列文档,并将 metaField
定义为字段 A
,则以后无法将字段 B
转换为 metaField
。但是,如果 A
的值是一个对象,则可以向 A
添加新的子字段。
注意
将数组用作 metaField
可能会导致意外的集合行为,因为数组相等性取决于特定顺序。
MongoDB 使用 metaField
对数据进行分区,以实现高效的组织和检索。创建时间序列集合时,MongoDB 将文档分组到存储桶中。存储桶中的文档共享相同的 metaField
值,并且具有非常接近的 timeField
值。
时间序列集合中的存储桶数量取决于唯一的 metaField
值的数量。与具有很少更改或从不更改的简单 metaField
值的集合相比,具有细粒度或动态 metaField
值的集合可能会生成更多、稀疏打包、短期的存储桶。细粒度和动态 metaField
值通常会降低存储和查询效率。
metaField
最佳实践
选择很少更改或从不更改的字段作为 metaField 的一部分。
如果可能,请选择过滤表达式中常用的标识符或其他稳定值作为 MetaField 的一部分。
避免选择不用于过滤的字段作为 MetaField 的一部分。取而代之的是,请使用这些字段作为测量值。
存储和关联基数
将数据插入时间序列集合时,内部集合会自动使用存储桶将数据组织成优化的存储格式。如果存在合适的存储桶,MongoDB 会将新数据插入该存储桶。如果不存在合适的存储桶,MongoDB会创建一个新存储桶。要优化存储,请选择很少更改的 metaField
,以创建具有更少、更密集的存储桶的时间序列集合。
具有精细或不断变化的 metaField
值的集合会生成许多稀疏打包的短期存储桶,从而增加集合的关联基数。增加关联基数会导致存储和查询效率降低。
粒度
您可以使用 granularity
参数指定 MongoDB 根据数据摄取率对时间序列数据进行存储的频率。下表显示了使用给定 granularity
值时一个数据桶中包含的最长时间间隔:
granularity | granularity 存储桶限额 |
---|---|
seconds | 1 小时 |
minutes | 24 小时 |
hours | 30天 |
默认情况下,granularity
设置为 seconds
。可以将 granularity
值设置为最接近同一数据源传入测量值之间的时间跨度,从而提高性能。例如,若要记录来自数千个传感器的天气数据,但每 5 分钟仅记录一次来自每个传感器的数据,请将 granularity
设置为 "minutes"
。添加新文档的频率越低,更粗粒度的存储和性能优势就越大。
将 granularity
设置为 hours
会将长达一个月的数据导入事件分组到单个存储桶中,从而拖延遍历时间并减慢查询速度。将其设置为 seconds
会导致每个轮询间隔有多个存储桶,其中许多可能只包含一个文档。
选择 granularity
值时,还应考虑典型查询。例如,如果您希望查询每次提取 1 天的数据,请使用“minutes”(分)。更精细的粒度(如 “seconds”(秒)) 会创建涵盖 1 小时数据的存储桶。这需要更多的存储桶来表示相同的数据,从而对存储和查询性能产生负面影响。较粗的粒度,如“hours”(小时)(存储桶跨度为 30 天),要求查询一次提取 30 天的数据,然后筛选掉大部分数据。
有关示例,请参阅设置时间序列数据的粒度。
压缩和硬件
当您将数据附加到已打开或重新打开的存储桶中时,所有时间序列集合都使用压缩存储桶格式。压缩缓存中的时间序列数据可支持高关联基数工作负载,同时保持高效的查询性能。