模型IOT数据
物联网(IoT)是一个连接到互联网的物理对象网络。许多这些设备,如传感器,会生成数据。
为了有效地存储和检索这些数据,您可以使用桶模式。
桶模式
将物联网数据组织起来的一种常见方法是将数据分组到桶中。桶化将特定的数据分组组织起来,以帮助
发现历史趋势,
预测未来趋势,以及
优化存储使用。
常用的分组数据参数包括
时间
数据源(如果您有多个数据集)
客户
数据类型(例如,财务数据中的交易类型)
注意
从MongoDB 5.0开始,时序集合是推荐用于时序数据的集合类型。请勿与时序集合一起使用桶模式,因为这可能会降低性能。
考虑一个存储从传感器获取的温度数据的集合。该传感器每分钟记录一次温度并将数据存储在一个名为temperatures
:
// temperatures collection { "_id": 1, "sensor_id": 12345, "timestamp": ISODate("2019-01-31T10:00:00.000Z"), "temperature": 40 } { "_id": 2, "sensor_id": 12345, "timestamp": ISODate("2019-01-31T10:01:00.000Z"), "temperature": 40 } { "_id": 3, "sensor_id": 12345, "timestamp": ISODate("2019-01-31T10:02:00.000Z"), "temperature": 41 } ...
的集合中。这种方法在数据和索引大小方面扩展性不好。例如,如果应用程序需要在sensor_id
和timestamp
字段上创建索引,则需要对传感器的每个传入读数进行索引以提高性能。
您可以使用文档模型将数据桶化到包含特定时间段测量的文档中。考虑以下更新的模式,它将每分钟的读数桶化到每小时的组中
{ "_id": 1, "sensor_id": 12345, "start_date": ISODate("2019-01-31T10:00:00.000Z"), "end_date": ISODate("2019-01-31T10:59:59.000Z"), "measurements": [ { "timestamp": ISODate("2019-01-31T10:00:00.000Z"), "temperature": 40 }, { "timestamp": ISODate("2019-01-31T10:01:00.000Z"), "temperature": 40 }, ... { "timestamp": ISODate("2019-01-31T10:42:00.000Z"), "temperature": 42 } ], "transaction_count": 42, "sum_temperature": 1783 }
此更新的模式提高了可扩展性,并反映了应用程序实际使用数据的方式。用户很可能不会查询特定的温度读数。相反,用户可能会查询一小时或一天的温度行为。桶模式通过将数据分组到统一的时间段来帮助实现这些查询。
结合计算模式和桶模式
的示例文档 包含两个计算字段:transaction_count
和 sum_temperature
。如果应用程序频繁需要检索特定小时的温度总和,计算累积的总和可以帮助节省应用程序资源。这种计算模式方法可以消除每次请求数据时都计算总和的需求。
预聚合的 sum_temperature
和 transaction_count
值允许进行进一步的计算,例如特定桶的平均温度(sum_temperature
/ transaction_count
)。用户更有可能查询应用程序在下午2:00至3:00之间的平均温度,而不是查询下午2:03的具体温度。桶化和预计算某些值使应用程序更容易提供此类信息。
MongoDB中的时间表示
MongoDB 默认以 UTC 存储时间,并将任何本地时间表示转换为这种形式。必须操作或报告某些未修改的本地时间值的应用程序可能将时区与 UTC 时间戳一起存储,并在其应用程序逻辑中计算原始的本地时间。
示例
在MongoDB shell中,您可以存储当前日期和客户端相对于UTC的偏移量。
var now = new Date(); db.data.insertOne( { date: now, offset: now.getTimezoneOffset() } );
通过应用保存的偏移量可以重构原始本地时间
var record = db.data.findOne(); var localNow = new Date( record.date.getTime() - ( record.offset * 60000 ) );