我正在搜索产品的标题和描述。它工作很酷,但我需要一个搜索喜欢得到一个结果优先。喜欢在结果中产品与标题匹配首先出现描述。 这是我的控制器代码:
def products
scope = Product.joins(:vendor).enabled.includes(:vendor, :images)
# Make sure to select only available vendors
scope = scope.where("vendors.enabled = ?", true)
# Filter by vendor
if params[:vendor_id].present?
scope = scope.where(vendor_id: params[:vendor_id])
end
if params[:search].present?
scope = scope.filter(params[:search])
end
scope
end
这是模特。 product.rb
def self.filter(search)
where("title ILIKE '%#{search}%' OR description ILIKE '%#{search}%'")
end
答案 0 :(得分:1)
因此,结果将是您有一组Product
个与其中一个字段中的搜索匹配的对象。
缺少的部分是,现在您需要对结果进行排序 - 您可以在查询中执行此操作,但这是相对艰苦的工作,我倾向于使用Ruby进行工作。
我首先会根据结果中搜索字词的出现次数生成结果分数,如下所示:
def score_result( result, search_term )
score = result.title =~ search_term ? 5 : 0
score+= result.text =~ search_term ? 1: 0
end
然后您可以将其作为搜索过滤器使用:
if params[:search].present?
searchPattern = Regexp.new(params[:search])
scope = scope.filter(params[:search]).sort_by { | res | score_result(res, searchPattern) }
end
这应该对术语在第一个中出现的结果进行排序,然后在出现在标题中的那些,然后出现在仅出现在文本中的那些结果。
有几点需要注意:
top hats and tails
会发生什么 - 您是否只想匹配该确切的短语?你应该拆分它,然后为每个单词分配一个分数?如果您这样做,是否要返回标题或文本包含and
作为搜索结果的结果?你怎么称重他们?如果一个单词匹配多次,那么该分数应该与每个匹配一次的不同单词一样高吗?