我是MongoDB的相对新手,但是根据我的阅读,有很多方法可以在MongoDB数据库中查找平均值和值的总和,每种方法都有各种优点和缺点。
我主要是要求一种方法,以尽可能高效(快速)的方法找到值的选择之和,以及选择值的平均值。
正在查询的集合中的文档类似于此结构(包含许多其他字段):
{
"_id": ObjectId('4e650107580fd649e5000005'),
"date_added": ISODate("2011-09-05T00:00:00Z"),
"value": 1500
}
在我的应用程序中,并非总是可以预先计算总和,因为要求求和的值的选择可以改变(基于日期范围 - 例如在开始日期和结束日期之间,平均值是多少)。这是预先计算平均值的类似问题。
据我所知,MapReduce绝对不适合实时(即按需)查询,所以这似乎也是不可能的。
目前我正在以这种方式查询集合:(注意:这是使用pymongo
)
response = request.db['somecollection'].find(
{
'date_added': {
'$gte': date_start,
'$lte': date_end
}
},
{
'value':1
}
).limit(500)
然后在响应中使用for
循环在Python中进行计算。 500结果的限制是任意的,以防止它变得太慢。我只检索值,而没有其他字段。
这是进行这种计算的最有效方法,还是有其他方法可以完成我需要的工作?
注意事项:
group
函数,因为我将来可能会使用分片修改
我应该指出,从我上面发布的查询返回的文档数量可以是1个文档到数百个,但最多可能有大约150个返回文档(平均约60或70)< / p>
答案 0 :(得分:4)
给地图减少尝试,它可能没有你想象的那么慢。我已经将它用于一些大型数据集的实时聚合,虽然它有时不闪电,但它通常很好。最好是你可以过滤掉你正在聚合的初始数据的大小,例如:
db.collection.mapReduce(m, r, { query : { year: 2011 } });
如果您需要加快速度,请考虑通过分片群集分发数据。然后,可以跨多个并行运行的分片扩展map-reduce处理。
答案 1 :(得分:3)
MongoDB备注
好的,所以Map / Reduce和聚合目前有一些严重的问题。
大警告: MongoDB实例只能有一个“javascript引擎”实例。这意味着您无法在服务器上同时运行两个Map / Reduces。而且你只有一个核心来运行map-reduce。
对于你正在做的事情,你基本上是“滚动自己的”M / R.缺点是额外的网络流量。好处是你现在可以在这个问题上投入更多核心(来自网络服务器)。
您的关键问题
我不能预先计算很多我的总和/平均数,因为总和/平均值的选择几乎总是不同的
没有用于优化“所有可能”查询的通用方法。如果您希望系统能够对每个范围的每个字段求和并聚合,那么您最终会找到一组太大的字段/范围。
“解决”这个问题的方法是减少字段和范围的集合。
因此请保持每日/每小时的计数器并对这些计数器求和。至少,您减少了需要扫描的文档数量,以便回答您的查询。
答案 2 :(得分:2)
简单的答案是:
但同时mongodb指南说:
使用MapReduce的价格是速度:组不是特别的 快速,但MapReduce较慢,不应该使用 “实时。”你运行MapReduce作为后台工作,它创建了一个 收集结果,然后您可以实际查询该集合 时间。
所以听起来mongodb不是实时数据聚合的最佳解决方案。
答案 3 :(得分:1)
MongoDB计划在版本2.1.1(目前定于2011年11月1日)中获得sum / avg / min / max等内容的本机聚合函数。有关详细信息和状态,请参阅以下问题:https://jira.mongodb.org/browse/SERVER-447