web-dev-qa-db-ja.com

MongoidとRubyで過去30日間の日付範囲をクエリしますか?

MongoidとRubyを使用して日付範囲(たとえば、過去30日後)をクエリするにはどうすればよいですか?

次のような配列またはハッシュを作成する必要があります。

{
    15 => 300,
    14 => 23,
    13 => 23
    ...
    30 => 20  # Goes over into previous month
    28 => 2
}

現在、各ドキュメントをDateTimeインスタンスとUNIXタイムスタンプの整数フィールドとともに保存しています。

上記のハッシュのキーは日であり、値はそれらの日のすべての売上の合計です。

何か案は?

15
SeanNieuwoudt

ルビーランドですべてを行う方法は次のとおりです。

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日時フィールドの名前が何であれ。

20
Dan Healy

より簡単な方法があります:

Sale.where(created_at: (30.days.ago..Time.now))

それに合わせて時間範囲を調整します。

28
tomblomfield

次のようなbetweenメソッドを使用してクエリを作成することもできます。

Sale.between(created_at: (30.days.ago..Time.now))
4
alup

モデルにタイムスタンプを入れるのを忘れた場合はどうなりますか? :(

問題ない! 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日付ヘルパー...

2
campeterson

これは、たとえば、関連するエントリ(日付値が指定した条件よりも大きいエントリ)のみを出力するマップ関数を使用してコレクションに対して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 } } })

それはうまくいくかもしれません。

0
Frost