我的收藏品包含一段时间内的货币汇率。我希望显示一个图表,我需要每小时只知道一个值。然而,我的数据更加密集,每秒钟只有一条记录。
如何降低记录密度,每小时只留一张。我不需要平均值,每小时的任何记录就足够了。
{
"_id" : ObjectId("52112613b45b5d057589009e"),
"date" : ISODate("2013-08-18T19:52:51.873Z"),
"rate" : 0.00007382007912027975,
"symbol" : "XAU=X"
}
{
"_id" : ObjectId("52112613b45b5d057589009f"),
"date" : ISODate("2013-08-18T19:52:52.273Z"),
"rate" : 0.00007382007912083746,
"symbol" : "XAU=X"
}
请在答案中考虑表现。
谢谢。答案 0 :(得分:1)
您可以使用聚合框架,但如果您真的关心性能,则应考虑将历史记录保留在预先聚合的集合中。
如果您可以使用除第一小时以外的记录,则可以省略$sort
阶段并直接转到$group
。
pipeline = [
{
"$sort" : {
"date" : 1
}
},
{
"$group" : {
"_id" : {
"symbol" : "$symbol",
"hour" : { "$hour" : "$date" },
"day" : { "$dayOfMonth" : "$date" },
"month" : { "$month" : "$date" },
"year" : { "$year" : "$date" }
},
"rate" : { "$first" : "$rate" },
"symbol" : { "$first" : "$symbol" },
"date" : { "$first" : "$date" }
}
},
{
"$project" : {
"date" : 1,
"symbol" : 1,
"rate" : 1,
"_id" : 0
}
}
]
db.foo.aggregate(pipeline)
答案 1 :(得分:1)
其他几个选项
上面的管道方法的问题是查询未经过优化,将扫描集合中的所有文档。我会在查询中添加日期范围,以提高效率。此外,该管道的硬限制为32MB。如果您有更多数据,则聚合将无效。