使用 Mongoid 和 Ruby 查询过去 30 天的日期范围?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7778464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 04:23:11  来源:igfitidea点击:

Querying last 30 days date range with Mongoid and Ruby?

rubymongodbmongoiddaterange

提问by SeanNieuwoudt

How do I go about querying a date range (of say the last 30 days from now) with Mongoid and Ruby?

我如何使用 Mongoid 和 Ruby 查询日期范围(比如从现在开始的最后 30 天)?

I need to end up with an array or hash like the following:

我需要以如下所示的数组或散列结束:

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

I am currently storing each document with a DateTime instance as well as a unix timestamp Integer field.

我目前正在使用 DateTime 实例和 unix 时间戳整数字段存储每个文档。

The keys in the above hash are the days and the values are the sum of all sales for those days.

上面散列中的键是天数,值是那些天的所有销售额的总和。

Any ideas?

有任何想法吗?

回答by tomblomfield

There's a simpler way:

有一个更简单的方法:

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

Adjust time range to suit.

调整时间范围以适应。

回答by Dan Healy

Here's how to do it all in rubyland:

以下是如何在 ruby​​land 中完成所有操作:

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

This will create a hash with "month-day" keys, reason is that some months have fewer than 30 days and will result in a key collision if the query is always 30.

这将创建一个带有“month-day”键的散列,原因是有些月份少于 30 天,如果查询始终为 30,则会导致键冲突。

If you want a different range, change the query:

如果您想要不同的范围,请更改查询:

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

Change created_atto whatever the name of your datetime field is.

更改created_at为日期时间字段的名称。

回答by alup

You can also write the query by using the betweenmethod like:

您还可以使用以下between方法编写查询:

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

回答by campeterson

What if you forgot to put timestamps in your model? :(

如果您忘记在模型中放置时间戳怎么办?:(

No problem! Just use the timestamp in the BSON:ObjectId

没问题!只需使用BSON:ObjectId 中的时间戳

Get Sales in the last 30 days.

获取过去 30 天内的销售额。

Sale.where(:id.gte => Moped::BSON::ObjectId.from_time((Date.today - 30).to_time))

Since the idfield is index, this may very well be the fastest query.

由于该id字段是索引,这很可能是最快的查询。

Need a date range? Cake.

需要日期范围?蛋糕。

Get Sales from last month.

获取上个月的销售额。

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

Of course this example assumes Rails date helpers...

当然,这个例子假设 Rails 日期助手......

回答by Frost

You can achieve this for example by doing a map_reducecall over your collection with a map function only emitting the relevant entries (the ones whose date value is greater than whatever condition you give it).

例如,您可以通过map_reduce使用 map 函数调用您的集合来实现这一点,该函数仅发出相关条目(日期值大于您提供的任何条件的条目)。

Try something like this:

尝试这样的事情:

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

That might work.

那可能会奏效。