2013-05-16 33 views
9

我有一个查询:

db.test.aggregate({$group : { _id : '$key', frequency: { $sum : 1 } } }) 

这将让测试组关键的每一个枚举的频率。基本上,我已经得到了钥匙的分配。

现在想象一下我想获得key1,key2和key3的分布(所以有三种不同的分布)。

很明显,我可以用每个单独的密钥运行这个查询3次,但似乎我们可以通过允许它同时计算所有3个密钥来优化查询。我一直在玩弄它并搜索整个网络间,但到目前为止,我委托运行三个单独的聚合查询或使用map/reduce函数。

有没有人有任何其他想法?

回答

6

有你在这里可以使用几种不同的方法:

  1. 使用的map/reduce:不这样做。现在运行聚合框架3次的速度要比使用map reduce功能更快。

  2. 运行聚合3次。这不是最优的,但如果你没有时间限制,那么这是最简单的选择。无论如何,如果您的聚合需要几秒钟,那么我不会担心优化,直到它们成为问题。

  3. 这是我能想到的最佳解决方法。 $group运营商允许您在多个字段上构建_id。例如。 {"_id":{"a":"$key1", "b":"$key2", "c":"$key3"}}。这样做会为所有现有的不同密钥组合创建一个分组。您可以用这种方式将您的密钥分组,然后手动在客户端中对结果进行求和。

让我详细说明一下。假设我们有一组形状。这些形状可以有颜色,大小和种类(正方形,圆形等)。在多密钥ID的集合可能看起来像:

db.shapes.aggregate({$group:{_id:{"f1":"$f1", "f2":"$f2", "f3":"$f3"}, count:{"$sum":1}}}) 

,并返回:

"result" : [ 
     { 
      "_id" : { 
       "f1" : "yellow", 
       "f2" : "medium", 
       "f3" : "triangle" 
      }, 
      "count" : 4086 
     }, 
     { 
      "_id" : { 
       "f1" : "red", 
       "f2" : "small", 
       "f3" : "triangle" 
      }, 
      "count" : 4138 
     }, 
     { 
      "_id" : { 
       "f1" : "red", 
       "f2" : "big", 
       "f3" : "square" 
      }, 
      "count" : 4113 
     }, 
     { 
      "_id" : { 
       "f1" : "yellow", 
       "f2" : "small", 
       "f3" : "triangle" 
      }, 
      "count" : 4145 
     }, 
     { 
      "_id" : { 
       "f1" : "red", 
       "f2" : "small", 
       "f3" : "square" 
      }, 
      "count" : 4062 
     } 

...等等

这样,你会总结成绩的客户端,大大减少了条目数量。假设每个关键字的唯一值数量与文档总数相比足够小,那么您可以在很短的时间内完成最后一步。