【发布时间】:2014-08-15 07:17:33
【问题描述】:
在迁移的数据 rails 2.3.10 应用程序上创建一个 rails 3.2.18 应用程序。 数据现在已完全编入索引(感谢 Pat!),但是搜索却出现了问题(由于旧版 SphinxQL 协议或旧版应用程序代码)。
我已经设法按照来自 this release note 的信息运行了一个初始化程序(sphinx 是 2.1.8,ts 是 3.1.1)一直在尝试照照镜子并告诉那个家伙给 RTFM
ThinkingSphinx::SphinxQL.functions!
并在 thinking_sphinx.yml 中添加了 utf 位
bin_path: /usr/local/bin
pid_file: /Users/me/r/fna/shared/tmp/searchd.pid
configuration_file: /Users/me/r/fna/config/development.sphinx.conf
log: /Users/me/r/fna/log/searchd.log
query_log: /Users/me/r/fna/log/searchd.query.log
indices_location: /Users/me/r/fna/shared/sphinx
64bit_timestamps: true
utf8: true
enable_star: true
min_infix_len: 2
max_matches: 1000
mysql41: 9312
mem_limit: 128M
在应用程序中运行搜索时出现以下错误
Sphinx 查询 (59.7ms) SELECT * FROM filodiretto_core WHERE MATCH('@filodirettotype_id 1 @site_id 1') AND sphinx_deleted = 0 ORDER BY @rank DESC LIMIT 0, 10 选项 max_matches=1000
在 126.4 毫秒内完成 500 内部服务器错误
ThinkingSphinx::SyntaxError (sphinxql: syntax error, unexpected USERVAR, expecting IDENT (or 6 other tokens) near '@rank DESC LIMIT 0, 10 OPTION max_matches=1000; SHOW META' - SELECT * FROM `filodiretto_core` WHERE MATCH('@filodirettotype_id 1 @site_id 1') AND `sphinx_deleted` = 0 ORDER BY @rank DESC LIMIT 0, 10 OPTION max_matches=1000; SHOW META):
app/controllers/filodirettos_controller.rb:22:in `risultati'
相关的控制者声明是
@results = @filodiretto_search.search.order('data_timestamp DESC')
由
管理class FilodirettoSearch < BaseSearch
accept :filodirettotype, :filodirettotype_id, :titolo, :domanda, :risposta, :site_id, :data, :terms
end
继承自类
class BaseSearch
PER_PAGE = 10
class_attribute :accepts, :base_class, :base_param, :per_page
attr_accessor :params
def self.accept(*accepts)
self.accepts = accepts
accepts += [:page]
self.send(:attr_accessor, *accepts)
end
def self.set_base_class(klass)
self.base_class = klass
end
def self.set_base_param(name)
self.base_param = name.to_sym
end
def self.set_per_page(per_page)
self.per_page = per_page
end
def base_param
self.class.base_param ||= self.class.to_s.underscore.to_sym
end
def base_class
@base_class ||= Kernel.const_get(self.class.to_s.sub('Search', ''))
end
def per_page
self.class.per_page ||= PER_PAGE
end
def initialize(params)
self.params = params
self.class.accepts.each do |param|
param_value = params[base_param][param]
if param.to_s =~ /id/
param_value = param_value.to_i unless param_value.blank?
end
instance_variable_set("@#{param}", param_value)
end
self.page = params[:page]
end
def search(options = {})
extra_conditions = options.delete(:conditions) || {}
order = options.delete(:order) || '@rank DESC'
extra_with = options.delete(:with) || {}
with = search_with.merge(extra_with)
conditions = search_conditions.merge(extra_conditions)
base_class.search sanitized_terms, :conditions => conditions, :with => with, :page => page, :per_page => per_page, :sort_mode => :extended, :order => order, :retry_stale => true, :match_mode => :extended
end
def sanitized_terms
@terms ||= ""
sanitize(@terms)
end
def sanitize(s)
if s.respond_to? :gsub
s.gsub("/", "\\/")
else
s
end
end
def search_with
with = {}
if params[base_param][:with]
params[base_param][:with].each do |k, v|
with[k] = case v
when 'true'
true
when 'false'
false
else
v
end
end
end
with
end
def search_conditions
conditions = {}
self.class.accepts.each do |condition|
if condition.to_s != 'terms'
conditions[condition] = sanitize(self.send(condition)) unless self.send(condition).blank?
end
end
conditions
end
end
更新
我看到了句法方法是如何改变很多事情的。可能整个推理需要重新思考。以前我有一个 model_search 来定义接受哪些属性
accept :filodirettotype, :filodirettotype_id, :titolo, :domanda, :risposta, :site_id, :data, :terms
这有点像 model_index 定义的重言式。
现在假设我想对 ID 和一般条款进行搜索
collection_select :filodiretto_search, :filodirettotype_id, Filodirettotype.all, :id, :name
text_field :filodiretto_search, :terms, :size => 35
filodirettotype 的 HABM 的索引位置
has filodirettotypes(:id), :as => :filodirettotype_id
似乎可以通过简洁的控制器语句使 BaseSearch 变得多余
比如:
@filodiretto_search = FilodirettoSearch.new params
@results = Filodiretto.search(params[:filodiretto_search][:terms], :with => {:filodirettotype_ids => params[:filodiretto_search][:filodirettotype_id]})
只有Filodiretto.search(params[:filodiretto_search][:terms]) 会生成正确的结果。但是条件语句生成:
Sphinx Query (1.0ms) SELECT * FROM `filodiretto_core` WHERE MATCH('solare @filodirettotype_id 1') AND `sphinx_deleted`
ActionView::Template::Error (index filodiretto_core: query error: no field 'filodirettotype_ids' found in schema
我看不出该机制如何通过单个字符串标准发挥作用
更新 2
使用 HABTM 实现多元化。索引定义也需要as 符号是复数形式。
has filodirettotypes(:id), :as => :filodirettotype_ids
并且控制器必须调用一个数组:
@results = Filodiretto.search(params[:filodiretto_search][:terms], :with => {:filodirettotype_ids => [params[:filodiretto_search][:filodirettotype_id]]})
不太热衷于在控制器中为值设置 if 语句 ==""
但是功能...
【问题讨论】:
标签: ruby-on-rails-3.2 sphinx thinking-sphinx