繁体   English   中英

Ruby-Rails-SQL查询-搜索词中的单词重新排序

[英]Ruby - Rails - SQL query - reordering words in a search term

我正在一个具有如下搜索功能的项目:

if params[:search_term].present? && params[:search_term].length > 1
  @candidates = @candidates.where("title like ?","%#{params[:search_term]}%")
end

客户要求我“放松”搜索-特别是单词order。 目前,如果有一个候选人的标题是“ White bar stool并且搜索“ White stool bar ,则不会返回任何结果。

我有什么办法可以执行忽略字序的查询? 还是对我来说,以不同的词序创建新的搜索词参数,进行多次搜索,然后组合结果会更好?

您可以考虑为此使用Arel Arel是rails / activerecord的基础查询汇编程序(因此没有新的依赖项),并且在构建复杂的查询时非常有用,因为它提供的深度远远超过高级ActiveRecord::QueryMethods

Arel提供了很多谓词匹配器供您选择,包括您的matches_anymatches_all 这些方法采用String Array ,并使用Like将它们分成单独的搜索条件。

例如,要搜索包含任何搜索到的单词的所有候选者,可以使用:

class Candidate < ActiveRecord::Base
  def self.search_for(term)
    candidates = Candidate.arel_table
    where(
       candidates[:title].lower.matches_any(
          term.split.map { |t| "%#{t.downcase}%" }
       )
    )
  end
end

search_for的最终结果(给定搜索词为“ White凳子栏”)为:

SELECT [candidates].*
FROM [candidates]
WHERE (
  LOWER([candidates].[title]) LIKE '%white%' 
  OR LOWER([candidates].[title]) LIKE '%stool%' 
  OR LOWER([candidates].[title]) LIKE '%bar%')

这似乎是您要寻找的。 如果必须匹配所有术语,则可以使用matches_all ,结果为:

SELECT [candidates].*
FROM [candidates]
WHERE (
  LOWER([candidates].[title]) LIKE '%white%' 
  AND LOWER([candidates].[title]) LIKE '%stool%' 
  AND LOWER([candidates].[title]) LIKE '%bar%')

有关所有可用的Arel谓词, 请参见此处

这增加了基本转义的好处,以避免SQL注入之类的事情。

您可以使用MySQL RLIKE运算符来匹配您可以使用句子创建的特定模式。

sentence = 'White stoll bar'
@candidates = @candidates.where('title RLIKE ?', "(#{sentence.tr(' ', '|')})")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM