Ruby mongodb计数相等对象

Ruby mongodb计数相等对象,ruby,mongodb,count,Ruby,Mongodb,Count,我有一个MongoDB数据库,其中的文档包含一个过滤器字段。这些文档如下所示: { "_id": ObjectId("503208f5b5db0135387d9249"), "name": "name1", "filter": "facebook" } { "_id": ObjectId("503208f5b5db0135387d9249"), "name": "name2", "filter": "twitter" } { "_i

我有一个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
我想按类型数数。这个例子应该是这样的:

{
   "_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 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 

我问了这个问题,但没有回答。 因此,如果你只有两种过滤方式:facebook和twitter,你可以通过两个查询来实现:

db.yourcollection.count({
  'filter' : 'facebook'
})
这将返回1

db.yourcollection.count({
  'filter' : 'twitter'
})
这将返回2个类似于:

其中,它显示了您如何运行这样一个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;
}
col.map_reduce(map, reduce,
        {
            :out => 'summary_collection',
            :raw => true
        }
      )
然后,它将输出到另一个集合(或内联,如果需要)以下格式的文档:

{
    _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:

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

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

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

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

然后,您可以通过提供字符串表示形式作为
\u id
来查询该筛选器的摘要集合,或者执行一个简单的
find()
来获得所有结果。

如果您说筛选器可以是任何东西,那么就不应该使用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;
};
减少功能:

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}

您使用的是哪个版本的mongo?您可以将聚合框架与
$match
$sum
或MR或预聚合一起使用。抱歉,没有阅读您的MongoDB版本。使用该版本,您只能执行映射缩减或预聚合来解决问题。我强烈建议升级您的数据库,因为1.6.3是一个非常旧的版本,缺少很多新功能和更好的查询处理等。筛选器可以是任何内容,它是字符串。筛选器可以是任何内容,它是字符串是的。它可以返回如下任何内容:{facebook:1203,twitter:201,where:200,othertype:400}这是什么代码?我不明白。此查询将运行到200.000多个文档,这会很慢吗?@RodrigoDias此代码不会实时工作。与SQL查询不同,聚合框架可以做到这一点,但不能减少映射。您需要将其输出到摘要集合,并将其存储为缓存,以便每5分钟左右更新一次MR(可能以增量方式)进行读取。当然,您仍然可以进行预聚合,这将解决实时问题,但这意味着您必须更改模式,以便为每个筛选器容纳一个总和字段。@RodrigoDias此代码是JavaScript。这是mongo控制台运行的代码。在Ruby中,您可以将每个函数的代码块包装在
BSON::code.new
中,然后调用实际的MR,比如:
col.map\u reduce(map,reduce,{:out=>{:inline=>true},:raw=>true})
没错,将map和reduce包装到函数中,并调用提提.collection.map\u reduce(map,reduce,:query=>{})。厚度