用日期范围思考狮身人面像
我正在为我的 Rails 应用程序实现全文搜索 API,到目前为止,Thinking Sphinx 取得了巨大成功。
我现在想要实现日期范围搜索,并不断收到“范围值错误”错误。
这是控制器代码的片段,我有点不知道下一步该做什么。
@search_options = { :page => params[:page], :per_page => params[:per_page]||50 }
unless params[:since].blank?
# make sure date is in specified format - YYYY-MM-DD
d = nil
begin
d = DateTime.strptime(params[:since], '%Y-%m-%d')
rescue
raise ArgumentError, "Value for since parameter is not a valid date - please use format YYYY-MM-DD"
end
@search_options.merge!(:with => {:post_date => d..Time.now.utc})
end
logger.info @search_options
@posts = Post.search(params[:q], @search_options)
当我查看日志时,我看到这一点,这似乎意味着日期尚未转换为与 Time.now.utc 相同的时间格式。
withpost_date2010-05-25T00:00:00+00:00..Tue Jun 01 17:45:13 UTC 2010
有什么想法吗?基本上,我试图让 API 请求传入“自”日期,以查看特定日期之后的所有帖子。我指定日期应采用 YYYY-MM-DD 格式。
感谢您的帮助。 Chris
编辑:我刚刚将日期参数合并语句更改为此
@search_options.merge!(:with => {:post_date => d.to_date..DateTime.now})
现在我 收到此错误
2010 年 5 月 25 日星期二
未定义方法“to_i”:日期所以显然还有一些设置不正确...
I am implementing a full text search API for my rails apps, and so far have been having great success with Thinking Sphinx.
I now want to implement a date range search, and keep getting the "bad value for range" error.
Here is a snippet of the controller code, and i'm a bit stuck on what to do next.
@search_options = { :page => params[:page], :per_page => params[:per_page]||50 }
unless params[:since].blank?
# make sure date is in specified format - YYYY-MM-DD
d = nil
begin
d = DateTime.strptime(params[:since], '%Y-%m-%d')
rescue
raise ArgumentError, "Value for since parameter is not a valid date - please use format YYYY-MM-DD"
end
@search_options.merge!(:with => {:post_date => d..Time.now.utc})
end
logger.info @search_options
@posts = Post.search(params[:q], @search_options)
When I have a look at the log, I am seeing this bit which seems to imply the date hasn't been converted into the same time format as the Time.now.utc.
withpost_date2010-05-25T00:00:00+00:00..Tue Jun 01 17:45:13 UTC 2010
Any ideas? Basically I am trying to have the API request pass in a "since" date to see all posts after a certain date. I am specifying that the date should be in the YYYY-MM-DD format.
Thanks for your help.
Chris
EDIT: I just changed the date parameters merge statement to this
@search_options.merge!(:with => {:post_date => d.to_date..DateTime.now})
and now I get this error
undefined method `to_i' for Tue, 25 May 2010:Date
So obviously there is something still not setup right...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可以说
d = "2010-12-10"
:post_date =>; (d.to_time.to_i..Time.now.to_i)
会让你到达那里。我刚刚在我的项目中这样做了,效果很好lets say
d = "2010-12-10"
:post_date => (d.to_time.to_i..Time.now.to_i)
would have gotten you there. I just did this in my project and it works great我终于解决了这个问题,但它采用了稍微不同的方法,但效果很好。
我试图将日期范围搜索放入 sphinx_scope (在模型中)或作为 :condition 或 :with (在控制器中)。这不起作用,所以我必须在模型中的 Define_index 内实现它。
因此,我所做的就是在 Define_index 中检查记录是否在某个日期范围内,该日期范围是由某些 SQL 代码定义的,如下所示。在本例中,我想查看“start_date”是否在现在到 30 天前的日期范围内,“end_date”是否在今天和 30 天后的日期范围内。
如果日期落在范围内,下面的代码会导致 :live 为 0 或 1,具体取决于它是在日期范围之外还是在日期范围之内(分别):
define index do
# 个字段:
...
#属性:
有“CASE WHEN start_date > DATE_ADD(NOW(), INTERVAL -30 DAY) AND end_date < DATE_ADD(NOW(), INTERVAL 30 DAY) THEN 1 ELSE 0 END”, :type = > :整数, :as => :直播
...
# 增量:
...
end
然后在你的控制器中,你所要做的就是检查是否 :live =>; 1 获取 start_dates 和 end_dates 在日期范围内的所有记录。
我使用了这样的 sphinx_scope:
sphinx_scope(:live) {
{ :with => {:直播=> 1 } }
}
然后在我的控制器中:
@models = Model.live.search(...)
为了确保它正常工作,您当然需要实现频繁的重新索引以确保索引是最新的,即正确的记录是:live => 1或0!
不管怎样,这对你来说可能有点晚了,但我实现了它,它的效果就像一个魅力!
I finally solved this, but it takes a slightly different approach but it works fine.
I was trying to put the date-range search inside a sphinx_scope (in the model) or as a :condition or :with (in the controller). This did not work, so instead I had to implement it inside the define_index in the model.
So what I did was put a check in the define_index to see if a record fell within a date range, the date range being defined by some SQL code, as shown below. In this case, I wanted to see if "start_date" fell within a date between now and 30 days ago, and an "end_date" fell within today and 30 days from now.
If the dates fell within the ranges, the code below causes the :live to be 0 or 1, depending on whether it falls outside or inside the date ranges (respectively):
define index do
# fields:
...
# attributes:
has "CASE WHEN start_date > DATE_ADD(NOW(), INTERVAL -30 DAY) AND end_date < DATE_ADD(NOW(), INTERVAL 30 DAY) THEN 1 ELSE 0 END", :type => :integer, :as => :live
...
# delta:
...
end
Then in your controller, all you have to do is check if :live => 1 to obtain all records that have start_dates and end_dates within the date ranges.
I used a sphinx_scope like this:
sphinx_scope(:live) {
{ :with => { :live => 1 } }
}
and then in my controller:
@models = Model.live.search(...)
To make sure it works well, you of course need to implement frequent reindexing to make sure the index is up to date, i.e. the correct records are :live => 1 or 0!
Anyway, this is probably a bit late for you now, but I implemented it and it works like a charm!!!
它会起作用吗?
如果你替换为
(似乎第一个没有返回预期格式的日期),
Wouldn't it work if you replaced
by
(It seems the first one doesn't return a date in the expected format)