我在查询时遇到了很多麻烦。我真的不知道怎么解释这个,但我会尝试。
基本上,我们有几个带有'posting_at'字段的对象,用于在日期时间字段中保存日期和时间以及时区。我需要查询并获取这些对象的日期范围。
以前,我将其转换为Date并将其与另一个Date对象进行比较。查询是这样的:
Date(posted_at) >= :start_date AND Date(posted_at) <= :end_date
但是,当Postgre将其转换为Date时,它会丢失时区信息,从而导致查询无法获得结果。
所以,我改为:
if start_date then
start_time = Time.zone.parse("#{start_date.year}-#{start_date.month}-#{start_date.day}")
conditions << "posted_at >= :start"
hash[:start] = start_time
end
if end_date then
end_time = Time.zone.parse("#{end_date.year}-#{end_date.month}-#{end_date.day}").end_of_day
conditions << "posted_at <= :end"
hash[:end] = end_time
end
虽然这可以获得准确的结果,但它的性能也很糟糕,并且在我的应用程序中造成一些超时。
我找不到任何其他方法来执行此查询并仍然保持准确的结果。有人会有一些建议或想法吗?
提前谢谢。
答案 0 :(得分:1)
您永远不想在您的数据库中存储时区信息。
这是一篇讨论一些陷阱的读物:
http://derickrethans.nl/storing-date-time-in-database.html
你会得到更好的结果,如tadman建议的那样:添加一个包含时间戳at time zone 'utc'
的新字段,然后将其编入索引。然后,您就可以使用posted_at between ? and ?
抓取内容。
答案 1 :(得分:0)
您可能有更多的运气将您的开始和结束时间转换为UTC,这将使得时区在进行查询时几乎无关紧要。这很容易做到:
start_date.to_time.to_datetime.beginning_of_day.utc
end_date.to_time.to_datetime.end_of_day.utc
您还可以将查询调整为:
posted_at BETWEEN :start AND :end
确保您搜索的字段也有索引,否则您的表现会非常糟糕。