Mongoid Group By or MongoDb group by in rails

时光怂恿深爱的人放手 提交于 2019-11-28 10:31:35

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

which would result in following result:

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

where _id is the course_id and count is the number of plays.

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.

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.

Using Mongoid

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

OR

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})

Follow the links below to group by using mongoid

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!