使用 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
非常昂贵。虽然语法不错,但我会选择 gte
和 lte
@oma - 您能否提供一些信息/链接,为什么 ruby 范围很昂贵,尤其是在这种情况下(mongodb 查询)?【参考方案2】:
这是在 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
这将使用“月-日”键创建一个哈希,原因是某些月份的天数少于 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 on Rails 是 mongodb - mongoid