4

次のような統計データを持つ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

コースの合計プレイ数の1日あたりのカウントを取得したいと思います。たとえば...8/1/12は2プレイ、8/2/12は6プレイでした。したがって、私は、course_idとactionとともにcreated_atタイムスタンプフィールドを使用します。問題は、Mongoidにgroupbyメソッドが表示されないことです。mongodbには現在1つあると思いますが、Rails3でそれがどのように行われるかはわかりません。

それぞれを使用してテーブルを実行し、増分を使用してレール内のマップまたはハッシュをハックすることはできますが、コースに100万ビューがある場合、100万を超えるレコードを取得して反復するのは面倒です。これを行うためのクリーンな方法はありますか?

4

2 に答える 2

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

ここ_idで、course_idcount再生回数です。

MongoDBには専用のグループメソッドもありますが、Mongoid3の裸のmongodbコレクションにアクセスする方法がわかりません。まだコードに飛び込む機会がありませんでした。

それほど重要ではないので、なぜドキュメントを発行するのか不思議に思うかもしれ{count: 1}ません。空のドキュメントなどを発行して、すべての値のresult.countに常に1を追加することもできます。特定のキーに対して1回だけ発行された場合(私の例では1回だけ再生された場合)、reduceは呼び出されないためcourse_id、結果として同じ形式でドキュメントを発行する方が適切です。

于 2012-08-20T08:10:13.663 に答える
4

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/

于 2016-01-08T12:24:25.087 に答える