2011-09-06 34 views
7

我是MongoDB的相对新手,但是从我读到的内容中可以找到各种方法来查找MongoDB数据库中的平均值和值,以及各种优点和缺点。MongoDB中的'AVG'和'SUM'功能,有什么提示?

我主要是要求一种方法,以尽可能高效(快速)的方法找到值的选择和值的选择的平均值之和。

集合中所查询的文件类似这种结构(有很多其他领域):

{ 
    "_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个结果的限制是任意的,以防止它变得太慢。我只是在检索价值,而没有其他领域。

这是做这种calculcation最有效的方法,还是有其他方法来完成我所需要的?

注意事项:

  • ,因为我可能会使用分片在未来
  • ,因为它是将用于在功能我不能用我的MapReduce不能使用group功能飞用户
  • 我不能预计算我的总和/平均值,因为总和/平均值的选择几乎总是不同的
  • 我看了看周围的计算器和网络尝试和找到如何做这种事情的建议,这是相当开放式

编辑:

我要指出的是,从我上面贴可以是任何的查询返回的文档数从1个文档到数百个,但可能会有大约150个返回文档的最大数量(平均大约60或70)

回答

4

给map-reduce尝试,它可能不像您想象的那么慢。我用它来实时聚合一些大型数据集,虽然它有时不是很快,但它通常很好。这是最好的,如果如果您需要更加快速度,考虑了分片集群分布数据可以过滤下来你聚集的初始数据,例如:

db.collection.mapReduce(m, r, { query : { year: 2011 } }); 

的大小。然后,map-reduce处理可以跨多个并行运行的分片进行扩展。

+0

我绝对会对MapReduce做更多的实验。我知道它会在数据集/查询/等之间有所不同,但在你的情况下,速度足以让用户不太注意(即不到半秒)? – johneth

+0

在500-5000毫秒之间变化,但某些数据集非常大(100M +文档),所以需要一个忙/进度指示器,但速度不够快。当JavaScript引擎从单线程SpiderMonkey升级到V8时,Map-Reduce性能也应该得到改善。 –

+0

啊,这听起来很有希望。目前我的数据集非常小(数以千计而不是数百万计),尽管这将随着时间的推移而增长。 – johneth

2

简单的答案是:

  1. 如果可以预先计算的一切,你可以预先计算。
  2. 如果您需要日期范围内的聚合数据,并且聚合应该尽可能快地运行,那么可以使用map/reduce + sharding将计算分布到多台机器上。

但同时MongoDB的指南说:

使用的MapReduce的价格是速度:基,没有特别 迅速,但MapReduce的是速度较慢,不应该在 使用“实时间“。您将MapReduce作为后台作业运行,它将创建一个 结果集合,然后您可以在实际的 时间内查询该集合。

所以这听起来像mongodb不是实时数据聚合的最佳解决方案。

+0

我绝对会预先计算出所有可能的值。不幸的是,我至少在一开始就被限制在一台机器上,所以我不能在多台机器上传播它。在我的例子中,返回文档的数量是否会影响使用MapReduce的足够速度? (我添加了回到我的问题底部的文件的平均数量) – johneth

3

MongoDB中指出

OK,这样的Map/Reduce和聚集有一些严重的问题,目前。

需要注意的是:MongoDB实例只能有一个“javascript引擎”实例。这意味着您不能在服务器上同时运行两个Map/Reduces。而你只有一个运行map-reduce的核心。

在你正在做什么的情况下,你基本上是“滚动自己的”M/R。缺点是额外的网络流量。好处是你现在可以在问题上(从网络服务器)抛出更多的核心。

你的关键问题

我不能预先计算我的很多款项/平均值,因为价值观的选择,总结/平均几乎总是不同

没有一般优化“所有可能”查询的方法。如果您希望系统能够对每个范围的每个字段进行汇总和汇总,那么您最终会发现一组太大的字段/范围。

“解决”的方法是减少字段和范围的集合。

因此,保持每日/每小时的柜台和这些柜台的总和。至少可以减少扫描所需的文档数量,以便回答您的​​查询。