seq*_*oia 24 time-series mongodb
我正在尝试将mongodb用于时间序列数据库,并且想知道是否有人可以建议如何最好地为该场景设置它.
时间序列数据与股票价格历史非常相似.我收集了来自不同机器的各种传感器的数据集.有十亿个时间戳的值,我想问下面的问题(最好是从数据库而不是应用程序级别):
对于给定的一组传感器和时间间隔,我希望按时间顺序排列在该间隔内的所有时间戳和传感器值.假设所有传感器共享相同的时间戳(它们都是同时采样的).
对于给定的一组传感器和时间间隔,我希望按时间顺序排列在给定间隔内的每个第k项(时间戳和相应的传感器值).
有关如何最好地设置并实现查询的任何建议?
谢谢你的建议.
jtr*_*ans 18
显然这是一个老问题,但是当我研究MongoDB的时间序列数据时,我遇到了它.我认为可能值得分享以下方法来提前分配完整文档并执行更新操作,而不是新的插入操作.请注意,这种方法在此处和此处都有记录.
想象一下,你每分钟都在存储数据.考虑以下文档结构:
{
timestamp: ISODate("2013-10-10T23:06:37.000Z"),
type: ”spot_EURUSD”,
value: 1.2345
},
{
timestamp: ISODate("2013-10-10T23:06:38.000Z"),
type: ”spot_EURUSD”,
value: 1.2346
}
Run Code Online (Sandbox Code Playgroud)
这与标准关系方法相当.在这种情况下,您为每个记录的值生成一个文档,这会导致大量的插入操作.我们可以做得更好.考虑以下:
{
timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"),
type: “spot_EURUSD”,
values: {
0: 1.2345,
…
37: 1.2346,
38: 1.2347,
…
59: 1.2343
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我们可以编写一个文档,并执行59次更新.这样做要好得多,因为更新是原子的,单个写入更小,并且还有其他性能和并发优势.但是,如果我们想在一个文档中存储整天,而不仅仅是整个小时,那该怎么办呢?这将要求我们沿着1440个条目走,以获得最后一个值.为了改进这一点,我们可以进一步扩展到以下内容:
{
timestamp_hour: ISODate("2013-10-10T23:00:00.000Z"),
type: “spot_EURUSD”,
values: {
0: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343},
1: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343},
…,
22: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343},
23: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343}
}
}
Run Code Online (Sandbox Code Playgroud)
使用这种嵌套方法,我们现在只需要步行,最多24 + 60即可获得当天的最后一个值.
如果我们使用填充预先填充所有值来构建文档,我们可以确保文档不会更改大小,因此不会移动.
Rus*_*ell 13
如果您不需要永久保存数据(即,您不介意它"老化"),您可能需要考虑"上限集合".加盖的集合有许多限制,这些限制反过来提供了一些有趣的好处,听起来很符合你想要的.
基本上,上限集合具有指定的大小,并且文档按插入顺序写入它直到它填满,此时它将包裹并开始用最新文档覆盖最旧的文档.您可以对上限集合中的文档执行的更新略有限制 - 即.您无法执行将更改文档大小的更新(因为这意味着需要在磁盘上移动以查找额外空间).我不认为这是你描述的问题.
结果是,您可以保证您的上限集合中的数据将按插入顺序写入磁盘并保持在磁盘上,这样可以非常快速地查询插入顺序.
顺便说一句,传感器及其产生的数据有何不同?如果它们相对相似,我建议将它们全部存储在同一个集合中以方便使用 - 否则将它们分开.
假设您使用单个集合,那么您的查询听起来非常可行.要记住的一件事是,要获得上限集合的好处,您需要根据集合的"自然"顺序进行查询,因此通过时间戳键查询将不会那么快.如果读数是定期读取的(所以你知道在给定的时间间隔内会有多少读数)我会建议如下查询1:
db.myCollection.find().limit(100000).sort({ $natural : -1 })
Run Code Online (Sandbox Code Playgroud)
例如,假设您每秒存储100个读数,上面将返回最后100秒的数据.如果你想要前100秒,你可以添加.skip(100000).
对于你的第二个查询,听起来像你需要MapReduce,但听起来并不是特别困难.您可以使用与上述类似的查询选择您感兴趣的文档范围,然后仅按照您对该map函数感兴趣的间隔选择一些文档.
以下是关于上限集合的Mongo文档:http://www.mongodb.org/display/DOCS/Capped+Collections
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
16950 次 |
| 最近记录: |