【问题标题】:Ruby - Rails - SQL query - reordering words in a search termRuby - Rails - SQL 查询 - 重新排序搜索词中的单词
【发布时间】:2017-06-19 14:27:50
【问题描述】:

我正在做一个搜索功能设置如下的项目:

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

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

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

【问题讨论】:

  • 您使用的是哪个数据库?
  • 这可能会有所帮助 - MySQL

标签: mysql sql ruby-on-rails ruby


【解决方案1】:

您可以考虑为此使用ArelArel 是 rails/activerecord 的底层查询组装器(因此没有新的依赖项),并且在构建复杂查询时非常有用,因为它提供的深度远远超过高级 ActiveRecord::QueryMethods

Arel 提供了大量的谓词匹配器选择,包括您的情况下的matches_anymatches_all。这些方法采用Strings 中的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(给定搜索词“白凳吧”)的最终结果是:

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%')

See Here 用于所有可用的Arel 谓词。

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

【讨论】:

  • 我什至不知道它与 rails 捆绑在一起 - 我现在正在阅读文档,非常感谢!
  • 此外,这个解决方案确实有效,我将来会使用更多,再次感谢
【解决方案2】:

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

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

【讨论】:

  • 这似乎很脆弱。我没有安装 MySQL,或者我会测试,但我假设如果搜索条件包含特殊字符,如括号、大括号、方括号、正斜杠等,则需要适当地转义这些字符,否则会出现查询错误.
  • 我想在测试之前我不应该接受...似乎没有返回任何结果:(
  • 我想知道为什么它似乎没有返回任何结果,这里有一个repo
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多