Mongoid Group By或MongoDb group by in rails

时间:2012-08-17 22:29:23

标签: ruby-on-rails ruby-on-rails-3 mongodb mongoid ruby-on-rails-3.2

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

所以我的课程如下......

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

我希望每天获得一个课程总数的数量。所以例如...... 8/1/12有2场比赛,8/2/12有6场比赛。等等。因此,我将使用created_at时间戳字段,使用course_id和action。问题是我没有看到Mongoid中的group by方法。我相信mongodb现在有一个,但我不确定如何在rails 3中完成。

我可以使用每个来运行表格,并在轨道中加入一些地图或散列,但是如果课程有100万个视图,那么检索和迭代超过一百万条记录可能会很麻烦。有干净的方法吗?

2 个答案:

答案 0 :(得分:8)

如评论中所述,您可以使用map / reduce来实现此目的。因此,您可以在模型中定义以下方法(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集合。我还没有机会深入研究代码。

您可能想知道为什么我发出文档{count: 1},因为它并不重要,我可能只是发出空文档或任何内容,然后总是为每个值的result.count添加1。问题是如果对特定键只进行了一次发射(在我的例子course_id中只播放了一次),则不调用reduce,因此最好以与结果相同的格式发出文档。

答案 1 :(得分:3)

使用Mongoid

stages =  [{ 
         "$group" => {  "_id" => { "date_column_name"=>"$created_at" }},
         "plays_count" => { "$sum" => 1 }
    }]
@array_of_objects = ModelName.collection.aggregate(stages, {:allow_disk_use => true})

stages =  [{ 
          "$group" => {  
             "_id" => { 
                       "year" => { "$year" => "$created_at" },
                       "month" => { "$month" => "$created_at" },
                       "day" => { "$dayOfMonth" => "$created_at" }
              }
           },
          "plays_count" => { "$sum" => 1 }
    }]
@array_of_objects = ModelName.collection.aggregate(stages, {:allow_disk_use => true})

按照以下链接使用mongoid分组

https://taimoorchangaizpucitian.wordpress.com/2016/01/08/mongoid-group-by-query/ https://docs.mongodb.org/v3.0/reference/operator/aggregation/group/