Mongo,在历史收藏中每小时只挑选第一笔交易

时间:2013-11-27 02:49:38

标签: mongodb summarization bigdata

我的收藏品包含一段时间内的货币汇率。我希望显示一个图表,我需要每小时只知道一个值。然而,我的数据更加密集,每秒钟只有一条记录。

如何降低记录密度,每小时只留一张。我不需要平均值,每小时的任何记录就足够了。

{
    "_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"
}

请在答案中考虑表现。

谢谢。

2 个答案:

答案 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)

其他几个选项

  1. 架构 - 创建并存储每小时摘要文档。添加新文档时,请更新“每小时”条目。如果你想求和,平均等,这种技术也很有效。此外,维护这个摘要的开销在所有操作中摊销。
  2. 查询 - 根据日期字段和限制(1)运行小时范围的查询,因为您可以使用任何行
  3. 上面的管道方法的问题是查询未经过优化,将扫描集合中的所有文档。我会在查询中添加日期范围,以提高效率。此外,该管道的硬限制为32MB。如果您有更多数据,则聚合将无效。