Mongoid Group By或MongoDb group by in rails [英] Mongoid Group By or MongoDb group by in rails

查看:54
本文介绍了Mongoid Group By或MongoDb group by in rails的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个mongo表,其中包含如下统计数据....

I have a mongo table that has statistical data like the following....

  • course_id
  • status which is a string, played or completed
  • and timestamp information using Mongoid's Timestamping feature

所以我的课如下...

so my class is as follows...

class Statistic
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Paranoia

  field :course_id, type: Integer
  field :status, type: String # currently this is either play or complete

我想获得一门课程每天总播放次数的计数.例如 12年8月1日有2场比赛,12年8月2日有6场比赛.等等,因此,我将使用带有"course_id"和"action"的created_at timestamp字段.问题是我没有在Mongoid中看到按方法分组.我相信mongodb现在有一个了,但是我不确定在rails 3中如何做到这一点.

I want to get a daily count of total # of plays for a course. So for example... 8/1/12 had 2 plays, 8/2/12 had 6 plays. Etc. I would therefore be using the created_at timestamp field, with course_id and action. The issue is I don't see a group by method in Mongoid. I believe mongodb has one now, but I'm unsure of how that would be done in rails 3.

我可以使用每个表浏览整个表,并以递增的方式一起破解一些地图或哈希,但是如果该课程具有100万个视图,则检索并迭代超过100万条记录可能会很混乱.有一种干净的方法可以做到这一点吗?

I could run through the table using each, and hack together some map or hash in rails with incrementation, but what if the course has 1 million views, retrieving and iterating over a million records could be messy. Is there a clean way to do this?

推荐答案

如注释中所述,您可以为此目的使用map/reduce.因此,您可以在模型中定义以下方法( http://mongoid.org/en/mongoid/docs /querying.html#map_reduce )

As mentioned in comments you can use map/reduce for this purpose. So you could define the following method in your model ( http://mongoid.org/en/mongoid/docs/querying.html#map_reduce )

def self.today
  map = %Q{
    function() {
      emit(this.course_id, {count: 1})
    }
  }

  reduce = %Q{
    function(key, values) {
      var result = {count: 0};
      values.forEach(function(value) {
        result.count += value.count;
      });
      return result;
    }
  }

  self.where(:created_at.gt => Date.today, status: "played").
    map_reduce(map, reduce).out(inline: true)
end

这将导致以下结果:

[{"_id"=>1.0, "value"=>{"count"=>2.0}}, {"_id"=>2.0, "value"=>{"count"=>1.0}}] 

其中_idcourse_idcount是播放次数.

MongoDB中也有专用的 group 方法,但我不确定如何使用Mongoid 3中裸露的mongodb集合.我还没有机会深入研究代码.

There is also dedicated group method in MongoDB but I am not sure how to get to the bare mongodb collection in Mongoid 3. I did not have a chance to dive into code that much yet.

您可能想知道为什么我发出一个文档{count: 1},因为它无关紧要,我本可以发出空文档或任何东西,然后对每个值始终向result.count加1.问题是,如果仅对特定键执行一次发射操作(在我的示例中course_id仅被播放一次),则不会调用reduce,因此最好以相同的格式发射文档.

You may wonder why I emit a document {count: 1} as it does not matter that much and I could have just emitted empty document or anything and then always add 1 to the result.count for every value. The thing is that reduce is not called if only one emit has been done for particular key (in my example course_id has been played only once) so it is better to emit documents in the same format as result.

这篇关于Mongoid Group By或MongoDb group by in rails的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆