使用 Mongoid 和 Ruby 查询最近 30 天的日期范围?

发布于 2024-12-09 18:23:20 字数 332 浏览 0 评论 0原文

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

我需要最终得到一个如下所示的数组或哈希:

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

我当前使用 DateTime 实例以及 unix 时间戳整数字段存储每个文档。

上述哈希中的键是日期,值是这些日期的所有销售额的总和。

有什么想法吗?

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

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.

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

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

冷情 2024-12-16 18:23:20

有一个更简单的方法:

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

调整时间范围以适应。

There's a simpler way:

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

Adjust time range to suit.

深海夜未眠 2024-12-16 18:23:20

以下是如何在 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

查询始终为 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 更改为日期时间字段的名称。

Here's how to do it all in rubyland:

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.

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_at to whatever the name of your datetime field is.

尾戒 2024-12-16 18:23:20

您还可以使用 Between 方法编写查询,例如:

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

You can also write the query by using the between method like:

Sale.between(created_at: (30.days.ago..Time.now))
情未る 2024-12-16 18:23:20

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

没问题!只需使用 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 日期助手...

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

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

Get Sales in the last 30 days.

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

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

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...

巨坚强 2024-12-16 18:23:20

例如,您可以通过使用仅发出相关条目(日期值大于您给出的任何条件的条目)的映射函数对集合进行 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 } } })

这可能有用。

You can achieve this for example by doing a map_reduce call 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).

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文