MongoidとRubyを使用して日付範囲(たとえば、過去30日後)をクエリするにはどうすればよいですか?
次のような配列またはハッシュを作成する必要があります。
{
15 => 300,
14 => 23,
13 => 23
...
30 => 20 # Goes over into previous month
28 => 2
}
現在、各ドキュメントをDateTimeインスタンスとUNIXタイムスタンプの整数フィールドとともに保存しています。
上記のハッシュのキーは日であり、値はそれらの日のすべての売上の合計です。
何か案は?
ルビーランドですべてを行う方法は次のとおりです。
sales_by_date = Hash.new(0)
Sale.where(:created_at.gte => (Date.today - 30)).order_by(:created_at, :desc).each do |s|
sales_by_date[s.created_at.strftime("%m-%d")] += 1
end
これにより、「月-日」キーを使用してハッシュが作成されます。理由は、月によっては30日未満であり、クエリが常に30の場合、キーの衝突が発生するためです。
別の範囲が必要な場合は、クエリを変更します。
# Between 10 and 20 days ago
start_day = 10
end_day = 20
Sale.where(:created_at.gte => (Date.today - end_day), :created_at.lte => (Date.today - start_day))
変化する created_at
日時フィールドの名前が何であれ。
より簡単な方法があります:
Sale.where(created_at: (30.days.ago..Time.now))
それに合わせて時間範囲を調整します。
次のようなbetween
メソッドを使用してクエリを作成することもできます。
Sale.between(created_at: (30.days.ago..Time.now))
モデルにタイムスタンプを入れるのを忘れた場合はどうなりますか? :(
問題ない! BSON:ObjectId のタイムスタンプを使用するだけです
過去30日間の売り上げを獲得します。
Sale.where(:id.gte => Moped::BSON::ObjectId.from_time((Date.today - 30).to_time))
id
フィールドはインデックスであるため、これが最速のクエリである可能性があります。
日付範囲が必要ですか?ケーキ。
先月から売上を上げます。
Sale.and(
{:id.gte => Moped::BSON::ObjectId.from_time((Date.today.prev_month.beginning_of_month).to_time)},
{:id.lte => Moped::BSON::ObjectId.from_time((Date.today.prev_month.end_of_month).to_time)}
)
もちろん、この例ではRails日付ヘルパー...
これは、たとえば、関連するエントリ(日付値が指定した条件よりも大きいエントリ)のみを出力するマップ関数を使用してコレクションに対してmap_reduce
呼び出しを実行することで実現できます。
次のようなものを試してください。
map = "function () { emit( {this.date.getDate(), {}} )}"
reduce = "function (key, values) { return {date: key, count: values.length } }"
collection.map_reduce(map, reduce, {query: {"date": {"$gt": 30.days.ago } } })
それはうまくいくかもしれません。