MongoDB - 对时间序列子文档进行范围查询
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB - 对时间序列子文档进行范围查询相关的知识,希望对你有一定的参考价值。
我是Mongo的新手,我只是围绕核心概念......我正在实现时间序列数据的模式,并且我打算尝试这里建议的模式:MongoDB as a Time Series Database,它也出现在一些Mongo演讲。
我理解架构,但是我很难弄清楚如何在一系列日期中查询它。更具体地说,有人可以展示如何在上面的链接查询架构以检索跨越多个小时/天的1分钟系列的示例吗?理想情况下,无需在Mongo之外进行后期处理。
Mongo文档和聚合管道主要关注处理数组而不是嵌套的子文档...... TIA。
编辑:为我试图解决的具体问题增加更多的清晰度...
假设我每隔1分钟存储一次数据,每天使用一个父文档,使用以下模式(从链接到上面的帖子中剪切):
{
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}
}
}
什么是最有效/最有效的方式来满足形式的查询:“给我一个按时间顺序排列的值列表,每分钟1,从2013-09-25在下午1:37开始,到2013-10-15结束下午2点56“?
@jtromans对你给出的链接有任何评论,应该指出你正确的方向:
...你应该继续“分类”你的数据,直到满足标准所需的最佳分辨率
假设你有一个类似如下的模式:
{
timestamp_hour: ISODate(...),
values: {
0: {},
1: {},
...
59: {}
}
}
然后你有一个每分钟的子文档,这将允许你相当简单地满足你的查询(例如,在第4分钟每次查找,例如:
collection.find({}, {"values.3": 1})
这只是一个仅过滤您感兴趣的分钟值的投影。由于它是全表扫描,您可能希望在timestamp_hour
字段中包含日期范围以限制搜索。如果您希望将值投影为更适合您期望的格式,则可以使用聚合,例如:
collection.aggregate([
{$project: {val: "$values.1"}}
])
如果您需要能够在数小时,几秒或其他时间段进行过滤,那么您需要使用容器中的容器或密钥,例如:分为秒和分钟:
{
timestamp_hour: ISODate(...),
minutes: {
0: {
seconds: {
0: ...
}
},
...
}
}
例如将其他值添加为键,以便对其进行索引和过滤:
{
timestamp_hour: ISODate(...),
hour_of_day: 0,
day_of_month: 1
minutes: {
...
}
}
请注意,我在这里使用了每小时文档的方法,您必须根据您的数据和要求决定是否适合您,或者您是否需要每分钟,每天等文档。
编辑:这是一个更好地匹配编辑问题的示例:
db.ts.aggregate([
{
$match: {
timestamp_hour: {$lte: {ISODate("2013-09-25")}, $gte: {ISODate("2013-10-15")}}
}
},
{
$project: {
hours: {$objectToArray: "$values"}
}
},
{
$unwind: "$hours"
},
{
$project: {
hour_index: "$hours.k",
minutes: {$objectToArray: "$hours.v"}
}
},
{
$unwind: "$minutes"
},
{
$project: {
reconstructed_date: {$dateFromParts: {
year: {$year: "$timestamp_hour"},
month: {$month: "$timestamp_hour"},
day: {$day: "$timestamp_hour"},
hour: "$hour_index",
minute: "$minutes.k",
}}
value: "$minutes.v"
}
},
{
$match: {
reconstructed_date: {$lte: {ISODate("2013-09-25T13:37:00.000Z")}, $gte: {ISODate("2013-10-15T14:56:00.000Z")}}
}
}
])
我并没有试图在这个时间段获得时区,这取决于你!
以上是关于MongoDB - 对时间序列子文档进行范围查询的主要内容,如果未能解决你的问题,请参考以下文章
我可以对索引子文档字段执行 MongoDB“开始于”查询吗?