显然这是一个老问题,但我在研究 MongoDB 以获取时间序列数据时遇到了这个问题。我认为可能值得分享以下方法来提前分配完整的文档并执行更新操作,而不是新的插入操作。请注意,此方法已记录在 here 和 here。
假设您每分钟都在存储数据。考虑以下文档结构:
{
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
}
这与标准的关系方法相当。在这种情况下,您会为每个记录的值生成一个文档,这会导致大量插入操作。我们可以做得更好。考虑以下几点:
{
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
}
}
现在,我们可以编写一个文档,执行 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}
}
}
使用这种嵌套方法,我们现在最多只需要步行 24 + 60 即可获得当天的最后一个值。
如果我们构建文档时所有的值都预先填充了填充,我们可以确定文档不会改变大小,因此不会被移动。