0

我的收藏包含一段时间内的货币汇率。我希望显示一个图表,我只需要知道每小时的一个值。但是我的数据要密集得多,大约每秒有一条记录。

我怎样才能降低记录的密度,每小时只留下一个。我不需要平均值,每小时的任何记录就足够了。

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

请在您的回答中考虑性能。

谢谢你。

4

2 回答 2

1

其他几个选项

  1. 架构 - 创建并存储每小时摘要文档。当您添加新文档时,更新“每小时”条目。如果您想求和、求平均值等,此技术也很有效。此外,维护此摘要的开销也分摊到所有操作中。
  2. 查询 - 根据日期字段和限制 (1) 对小时范围运行查询,因为您对任何行都满意

上面管道方法的问题是查询没有优化,并且会扫描集合中的所有文档。我会在查询中添加一个日期范围以提高效率。此外,管道的硬限制为 32MB。如果您拥有的数据多于该数据,则聚合将不起作用。

于 2013-11-27T03:34:26.167 回答
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)
于 2013-11-27T03:25:58.883 回答