MongoDB中的'AVG'和'SUM'功能,有什么提示吗?

时间:2011-09-06 09:58:03

标签: mongodb nosql

我是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函数,因为我将来可能会使用分片
  • 我无法使用MapReduce,因为它是一个将由用户即时使用的功能
  • 我不能预先计算很多我的总和/平均数,因为总和/平均值的选择几乎总是不同的
  • 我已经查看了stackoverflow和网络,试图找到关于如何做这种事情的建议,并且它是相当开放的

修改

我应该指出,从我上面发布的查询返回的文档数量可以是1个文档到数百个,但最多可能有大约150个返回文档(平均约60或70)< / p>

4 个答案:

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

简单的答案是:

  1. 如果有可能预先计算出你可以预先计算的所有内容。
  2. 如果您需要按日期范围汇总数据,汇总应尽可能快地运行,然后使用map / reduce + sharding在多台计算机上分配计算。
  3. 但同时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