Ric*_*lse 6 sunspot sunspot-rails
我正在使用acts_as_solr将Rails应用程序转换为太阳黑子.
该应用程序使用在acts_as_solr中公开的solr中的字段搜索功能.你可以给它一个像这样的查询字符串:
title:"The thing to search"
Run Code Online (Sandbox Code Playgroud)
它会在标题字段中搜索该字符串.
在转换为太阳黑子时,我正在解析查询字符串的字段特定部分,我需要动态生成搜索块.像这样的东西:
Sunspot.search(table_clazz) do keywords(first_string, :fields => :title) keywords(second_string, :fields => :description) ... paginate(:page => page, :per_page => per_page) end
如果查询需要,还需要执行持续时间(秒,整数)范围和否定,这很复杂.
在当前系统上,用户可以在标题中搜索某些内容,不包括在其他字段中包含其他内容的记录,并按持续时间确定范围.
简而言之,如何动态生成这些块?
我自己已经解决了这个问题。我使用的解决方案是将所需的范围编译为字符串,连接它们,然后在搜索块内评估它们。
这需要一个单独的查询构建器库来询问 solr 索引,以确保不会为不存在的索引字段创建范围。
该代码非常适合我的项目,而且太长,无法完整发布,但这就是我所做的:
1. 拆分搜索词
这给了我一个术语或术语加字段的数组:
['field:term', 'non field terms']
2. 这被传递到查询构建器。
构建器根据可用索引将数组转换为范围。此方法是一个示例,它采用模型类、字段和值,并在字段已建立索引时返回范围。
def convert_text_query_to_search_scope(model_clazz, field, value)
if field_is_indexed?(model_clazz, field)
escaped_value = value.gsub(/'/, "\\\\'")
"keywords('#{escaped_value}', :fields => [:#{field}])"
else
""
end
end
Run Code Online (Sandbox Code Playgroud)
3.加入所有范围
生成的范围被连接起来join("\n")
并被eval
编辑。
这种方法允许用户选择他们想要搜索的模型,并且可以选择进行特定领域的搜索。然后,系统将仅搜索具有任何指定字段(或公共字段)的模型,而忽略其余字段。
检查字段是否被索引的方法是:
# based on http://blog.locomotivellc.com/post/6321969631/sunspot-introspection
def field_is_indexed?(model_clazz, field)
# first part returns an array of all indexed fields - text and other types - plus ':class'
Sunspot::Setup.for(model_clazz).all_field_factories.map(&:name).include?(field.to_sym)
end
Run Code Online (Sandbox Code Playgroud)
如果有人需要它,请检查可排序性:
def field_is_sortable?(classes_to_check, field)
if field.present?
classes_to_check.each do |table_clazz|
return false if ! Sunspot::Setup.for(table_clazz).field_factories.map(&:name).include?(field.to_sym)
end
return true
end
false
end
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1813 次 |
最近记录: |