首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >mongodb计数等于对象

mongodb计数等于对象
EN

Stack Overflow用户
提问于 2012-10-25 19:03:03
回答 3查看 675关注 0票数 0

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

代码语言:javascript
运行
复制
{
   "_id": ObjectId("503208f5b5db0135387d9249"),
   "name": "name1",
   "filter": "facebook"
}          {
   "_id": ObjectId("503208f5b5db0135387d9249"),
   "name": "name2",
   "filter": "twitter"
}  
{
   "_id": ObjectId("503208f5b5db0135387d9249"),
   "name": "name3",
   "filter": "twitter"
}    

我想按类型计数。此示例应如下所示:

代码语言:javascript
运行
复制
facebook => 1, twitter => 2

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

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

代码语言:javascript
运行
复制
{facebook : 1203, twitter : 201, wherever : 200, othertype : 400}

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

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

它终于起作用了。下面是ruby驱动程序的代码:

代码语言:javascript
运行
复制
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 
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-25 19:53:36

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

它显示了如何运行MR,如下所示:

代码语言:javascript
运行
复制
var map = function(){
    emit(this.filter,1);
}

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

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

    return count;
}

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

代码语言:javascript
运行
复制
{
    _id: facebook,
    value: 1,
    _id: twitter,
    value: 2
}

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

代码语言:javascript
运行
复制
map = BSON::Code.new "function() { emit(this.filter, 1); }"

然后像这样运行MR:

代码语言:javascript
运行
复制
col.map_reduce(map, reduce,
        {
            :out => 'summary_collection',
            :raw => true
        }
      )

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

票数 0
EN

Stack Overflow用户

发布于 2012-10-25 19:36:24

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

代码语言:javascript
运行
复制
db.yourcollection.count({
  'filter' : 'facebook'
})

这将返回1

代码语言:javascript
运行
复制
db.yourcollection.count({
  'filter' : 'twitter'
})

这将返回2

票数 0
EN

Stack Overflow用户

发布于 2012-10-25 20:42:15

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

这是一个有效的代码,将其放入mongo控制台,然后将其转换为ruby。

首先创建map函数:

代码语言:javascript
运行
复制
var map = function(){
  emit(this.filter, 1);
}

reduce函数:

代码语言:javascript
运行
复制
var reduce = function(key, value){
  var n = 0;
  value.forEach(function(v){
     n+=v;
  });
  return n;
};

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

代码语言:javascript
运行
复制
res = db.runCommand({
  'mapreduce' : 'YOURCOLLECTION',
  'map' : map,
  'reduce' : reduce,
  'out' : 'tmp'
});
db.tmp.find();

这将返回给您

代码语言:javascript
运行
复制
{'_id' : 'facebook', 'value' : 1},
{'_id' : 'twitter', 'value' : 2}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13067189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档