1

我有一个 MongoDB 数据库,其中包含包含过滤器字段的文档。文件如下所示:

{
   "_id": ObjectId("503208f5b5db0135387d9249"),
   "name": "name1",
   "filter": "facebook"
}          {
   "_id": ObjectId("503208f5b5db0135387d9249"),
   "name": "name2",
   "filter": "twitter"
}  
{
   "_id": ObjectId("503208f5b5db0135387d9249"),
   "name": "name3",
   "filter": "twitter"
}    

我想按类型计数。这个例子应该是这样的:

facebook => 1, twitter => 2

使用 ruby​​ 代码,计数非常慢。

过滤器是一个字符串,可以是任何东西。例如:

{facebook : 1203, twitter : 201, wherever : 200, othertype : 400}

我正在使用 mongo 映射器(红宝石驱动程序)。

============== 编辑3

最后它的工作。这是红宝石驱动程序的代码:

def map  
    'function(){  
        emit(this.plataforma, 1);
    }'  
end   
def reduce   
    '
    function(prev, current) {  
        var n = 0;
        current.forEach(function(v){
            n+=v;
        });
        return n; 
    }'
end 

def build  
    Mention.collection.map_reduce(map, reduce, :query => {})  
end 
4

3 回答 3

0

我问了这个问题,但没有任何答案。因此,如果您只有 2 种过滤器的可能性:facebook 和 twitter,您可以通过两个查询来做到这一点:

db.yourcollection.count({
  'filter' : 'facebook'
})

这将返回你 1

db.yourcollection.count({
  'filter' : 'twitter'
})

这将返回你 2

于 2012-10-25T11:36:24.200 回答
0

这类似于:http ://cookbook.mongodb.org/patterns/count_tags/

它在哪里显示了如何像这样运行 MR:

var map = function(){
    emit(this.filter,1);
}

var reduce  = function(previous,current){
    var count = 0;

    for (index in current) {
        count += current[index];
    }

    return count;
}

然后它将输出到另一个集合(如果需要,可以内联)格式的文档:

{
    _id: facebook,
    value: 1,
    _id: twitter,
    value: 2
}

这是用 JS 的 MongoDB 控制台语言编写的。MongoDB 有一个内置的 JavaScript 解析器 (spidermonkey) 可以解析 MR 函数。在 Ruby 中,您可以像这样封装您的函数:

map = BSON::Code.new "function() { emit(this.filter, 1); }"

然后像这样运行 MR:

col.map_reduce(map, reduce,
        {
            :out => 'summary_collection',
            :raw => true
        }
      )

然后,您只需通过提供字符串表示形式来查询该过滤器的摘要集合,_id或者执行简单的操作find()以获取所有结果。

于 2012-10-25T11:53:36.080 回答
0

如果你说过滤器可以是任何东西——那么你应该使用 mapreduce。 http://www.mongodb.org/display/DOCS/MapReduce

这是一个工作代码,将其放在 mongo 控制台中,然后将其转换为 ruby​​。

首先创建地图功能:

var map = function(){
  emit(this.filter, 1);
}

减少功能:

var reduce = function(key, value){
  var n = 0;
  value.forEach(function(v){
     n+=v;
  });
  return n;
};

因为您使用的是旧版本的 mongo,所以您必须执行以下操作:

res = db.runCommand({
  'mapreduce' : 'YOURCOLLECTION',
  'map' : map,
  'reduce' : reduce,
  'out' : 'tmp'
});
db.tmp.find();

这将返回你

{'_id' : 'facebook', 'value' : 1},
{'_id' : 'twitter', 'value' : 2}
于 2012-10-25T12:42:15.243 回答