mongodb数等于对象

时间:2012-10-25 11:03:03

标签: ruby mongodb count

我有一个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代码,计数非常慢。

过滤器是一个String,可以是任何东西。 E.g:

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

我正在使用mongo mapper(ruby驱动程序)。

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

最后它正在发挥作用。这是ruby驱动程序的代码:

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 

3 个答案:

答案 0 :(得分:0)

我问了这个问题,但没有任何答案。 因此,如果您只有2种过滤器可能性:facebook和twitter,您可以使用两个查询执行此操作:

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

这将使你返回1

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

这将使你返回2

答案 1 :(得分: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
}

这是用MongoDBs控制台语言编写的,即JS。 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()即可获得所有结果。

答案 2 :(得分: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}