代码之家  ›  专栏  ›  技术社区  ›  Renan Tomal Fernandes

Rails:一个好的搜索算法

  •  0
  • Renan Tomal Fernandes  · 技术社区  · 15 年前

    我正试图返回更像搜索的结果

    我现在的算法是

    def search_conditions(column, q)
      vars  = []
      vars2 = []
    
      vars << q
    
      if q.size > 3
        (q.size-2).times do |i|
          vars2 << q[i..(i+2)]
          next if i == 0
          vars << q[i..-1]
          vars << q[0..(q.size-1-i)]
          vars << q[i % 2 == 0 ? (i/2)..(q.size-(i/2)) : (i/2)..(q.size-1-(i/2))] if i > 1
        end
      end
    
      query = "#{column} ILIKE ?"
      vars = (vars+vars2).uniq
    
      return [vars.map { query }.join(' OR ')] + vars.map { |x| "%#{x}%" }
    end
    

    如果我搜索“RubyonRails”,它将有4种搜索方式。

    1)删除左字母“uby on rails”…“ils”

    2)删除右字母“ruby on rail”…“rub”

    3)删除左右字母“uby on rails”、“uby on rail”……关于“

    4)仅使用3个字母“rub”、“uby”、“by”、“y o”、“on”……ILS”

    使用这四种方法是好的吗?还有吗?

    3 回复  |  直到 15 年前
        1
  •  6
  •   pkaeding    15 年前

    为什么要删除这些字母?您是否试图确保如果有人搜索“小部件”,您也将匹配“小部件”?

    如果是这样,你要做的就是 stemming 它比删除前导和尾随字母要复杂得多。您也可能有兴趣删除' stop words '来自您的查询。这些是构成语法正确的句子所必需的极为常见的单词,但对搜索不太有用,例如“a”、“the”等。

    正确搜索是一个非常复杂和困难的问题。我建议你不要试图自己解决它,而是把注意力集中在网站的核心目标上。也许您可以利用 Lucene 在代码中进行项目。此链接也可能有助于 using Lucene in Ruby on Rails .

    我希望这有帮助;我意识到我有点回避了你最初的问题,但我真的不建议你自己去解决这个问题。

        2
  •  2
  •   Alex Reisner    15 年前

    正如pkading所说,词干太复杂,无法尝试自己实现。但是,如果您希望在MySQL中搜索相似(不精确)的字符串,并且您的用户搜索词非常接近数据库字段的完整值(即,您没有在大量文本中搜索单词或短语),则可能需要尝试使用 Levenshtein distance . 这里是一个 MySQL implementation .

    Levenshtein算法将允许您进行“模糊”匹配,给您一个相似性分数,并帮助您避免安装和配置搜索守护进程,这很复杂。然而,这实际上只是一个非常具体的案例,而不是一般的网站搜索。

        3
  •  1
  •   Evolve    15 年前

    同时,所有人都在建议其他可能的解决方案,请看:

    Sphinx -如何实现对1000多万行表的全文搜索,跟上负载,并保持相关性?斯芬克斯擅长这些谜语。

    Thinking Sphinx -斯芬克斯和ActiveRecord之间的红宝石连接器。

    推荐文章