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

Posted

技术标签:

【中文标题】使用 Mongoid 和 Ruby 查询最近 30 天的日期范围?【英文标题】:Querying last 30 days date range with Mongoid and Ruby? 【发布时间】:2011-12-08 08:56:14 【问题描述】:

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

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


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

我目前正在使用 DateTime 实例以及 unix timestamp Integer 字段存储每个文档。

上述哈希中的键是天数,值是那些天所有销售额的总和。

有什么想法吗?

【问题讨论】:

【参考方案1】:

有一个更简单的方法:

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

调整时间范围以适应。

【讨论】:

这需要 .days.ago 部分的 ActiveSupport 我认为您不能以这种方式使用哈希语法添加多个参数。不过可能是错的。 @AshBlue - 它是 Range 类型的单个参数。 ruby-doc.org/core-2.0.0/Range.html ruby 中的 Range 非常昂贵。虽然语法不错,但我会选择 gtelte @oma - 您能否提供一些信息/链接,为什么 ruby​​ 范围很昂贵,尤其是在这种情况下(mongodb 查询)?【参考方案2】:

这是在 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 更改为您的日期时间字段的名称。

【讨论】:

如果使用2012-06-16 而不是(Date.today - 30) 那么如何编写查询? @harsh4u:首先将字符串转换为 Date 对象。 Date.parse("2012-06-16") 这远非完美的解决方案,下面的答案要好得多。 Sale.where(:end_date.gte => (Date.today), :begin_date.lte => (Date.today)).order(begin_date: :desc)【参考方案3】:

您也可以使用between 方法编写查询,例如:

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

【讨论】:

【参考方案4】:

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

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

【讨论】:

我认为这是更好的答案。它比较困难,但它有很好的性能。谢谢!【参考方案5】:

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

这可能行得通。

【讨论】:

以上是关于使用 Mongoid 和 Ruby 查询最近 30 天的日期范围?的主要内容,如果未能解决你的问题,请参考以下文章

批量查找 mongoDB 记录(使用 mongoid ruby​​ 适配器)

如何使用 ruby​​ 编程设置 mongoid

rails查询mongodb通用查询

Ruby on Rails 是 mongodb - mongoid

Ruby on Rails - Criteria - Mongoid - where 条件为 2 x 2 列

Mongoid 在 ruby​​ 1.9.3 上失败