0


1

Rails:優れた検索アルゴリズム

検索のような結果を返そうとしています

私の現在のアルゴリズムはこれです

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

「Ruby on Rails」を検索すると、4つの検索方法が作成されます。

1)左の文字「uby on Rails」..「ils」を削除

2)「Ruby on Rail」..「Rub」という正しい文字を削除する

3)左右の文字「uby on Rails」、「uby on Rail」を削除 . 「オン」

4)「Rub」、「uby」、「by」、「y o」、「on」の3文字のみを使用して…​ 「ils」

これらの4つの方法を使用するのは良いですか? もうありますか?

3 Answer


6


なぜこれらの文字を削除するのですか? 誰かが「ウィジェット」を検索した場合、「ウィジェット」にも一致することを確認しようとしていますか?

もしそうなら、あなたがやろうとしていることは「http://en.wikipedia.org/wiki/Stemming[stemming]」と呼ばれ、先頭と末尾の文字を削除するよりもはるかに複雑です。 クエリから「http://en.wikipedia.org/wiki/Stop_words [ストップワード]」を削除することもできます。 これらは、文法的に正しい文を作成するために必要な非常に一般的な単語ですが、「a」、「the」など、検索にはあまり役立ちません。

検索を正しく行うことは、非常に複雑で難しい問題です。 自分で解決するのではなく、サイトの中心的な目的に焦点を当てることをお勧めします。 おそらく、コードでhttp://lucene.apache.org/[Lucene]プロジェクトの検索機能を活用できます。 このリンクは、http://geekblog.vodpod.com/2009/03/09/using-solr-lucene-for-search-with-ruby-on-rails/ [Ruby on RailsでLuceneを使用]にも役立ちます。

これがお役に立てば幸いです。私はあなたの元の質問をやや避けたようですが、自分でこれに取り組むことは本当にお勧めしません。


2


pkaedingが言うように、ステミングはあまりにも複雑すぎて、自分で実装しようとすることはできません。 ただし、MySQLで類似の(正確ではない)文字列を検索し、ユーザー検索用語がデータベースフィールドの完全な値に非常に近い場合(つまり、大量のテキストで単語やフレーズ)、http://en.wikipedia.org/wiki/Levenshtein_distance [Levenshtein distance]を使用してみてください。 これはhttp://www.artfulsoftware.com/infotree/queries.php?&bw=1045#552[MySQL実装]です。

Levenshteinアルゴリズムにより、「ファジー」マッチングが可能になり、類似性スコアが得られ、複雑な検索デーモンのインストールと構成を回避できます。 ただし、これは実際には非常に特殊なケースのみであり、一般的なサイト検索ではありません。


1


すべて他の可能な解決策を提案していたが、チェックアウト:

Sphinx-その1,000万を超える行テーブルに全文検索を実装し、負荷に追いつき、関連性を維持するにはどうすればよいですか? スフィンクスはそのようななぞなぞが得意です。

Thinking Sphinx-SphinxとActiveRecordの間のRu​​byコネクター。