我正在尝试为多个更新的值之和设置时间排序查询。在任何时候都可以添加一个值,任何查询都会根据指定时间范围内该值的更改总数(delta)返回订购的文档。
在这种特定情况下,长期保留在文档中,并随时添加到任何合理的金额。我想检索文档,按指定时间之后的所有更新的总和排序。时间将是一小部分选项,例如先前一小时,或一天,一个月,一年等。可以修改文档结构以满足这些需求或其他集合等。
解决方案必须适合在REST api中使用,这仅与更新和查询可能非常频繁相关。但是,准确性不需要是完美的,因此在大致时间段内改变的总和的近似值是可以接受的。
我在想一个可能的解决方案是设置一个单例,将存储更新信息的事件中的数据聚合到一个单独的集合中,形成较小的时间间隔,并从一个简单的查询中检索,IE总和为小时总计和更新这个总计每5分钟左右,更新频率更低的时间段(每日查询每小时,每天每月等),这是表现所必需的。使用此解决方案,此嵌入文档中的数据将类似于
{
_id: ObjectId,
total: long, // used for all time query
hour: long, // aggregated every 5 min
day: long, // aggregated every hour
month: long, // aggregated every day
year: long, // aggregated every week
}
并且个别事件将类似于
{
_id: ObjectId,
reference: ObjectId, // matches documents of type above
updateTime: Date, // used by aggregator
amount: long, // added to total
}
可以将查询作为
db.collection.find({$query:{},$orderBy:{hour:-1}})
这样做的另一个好处是,如果需要查询特定范围内的更新,可以存档更新事件以供使用,尽管在解决方案中不需要这样做
有什么替代方案,比较哪些优点/缺点?
似乎与MongoDB MapReduce update in place how to有类似的解决方案。是否有任何明显的问题,例如缩放,可以通过不同的解决方案来避免?
编辑:我应该更明确地说明,订单本身就是重要的,只有总价值,无论何时更新并且可以单独维护,都与API相关。近似排序也是可以接受的。
答案 0 :(得分:1)
您尝试实施的内容称为“时间序列”。
在'mongodb.com'网站上有很多关于该主题的好帖子和演示文稿,首先是:
http://blog.mongodb.org/post/65517193370/schema-design-for-time-series-data-in-mongodb
看看这些,它将帮助您设计解决方案。
我可以从你的描述中说出一些事情。
如果可以,您希望使用聚合框架而不是map / reduce。它更容易,而且大多数时候性能更高。
使用2个集合,一个用于数据,一个用作“数据仓库”通常是一个很好的设计。这样,您可以在需要时修剪数据,也可以使用自动执行此操作的上限集合。 TTL集合也是让一些数据过期的另一种选择。
运行常规聚合来计算5分钟,小时,天,......统计数据是一个很好的模式。如果您没有性能问题,您可能希望保持这种方式。如果您拥有稀缺资源,则可以降低运行频率,或者设计更复杂的方案来仅计算增量。例如,不是总是计算每小时最后一天的结果,而是仅计算最后一小时的统计数据,保留24个数据点,然后将这些数据组合起来以获得“日期”值。但同样,这是一个更复杂的方案和设计,你可能不需要它。
总之,请查看有关“时间序列”的一些现有演示文稿,因为这是使用MongoDB的常见模式。