Rails + Sphinx =? パートI

Ruby on Rails検索についてお聞かせください。



ストーリーを2つの部分に分けることにしました。最初の部分では、退屈なプロジェクトのセットアップと、1つのモデルの1つのフィールドでの簡単な検索です。 第二に、私たちは複雑さについて詳しく調べ、プラグインができることすべてについて話そうとします。 ちなみに、ソースコード(テキスト内のリンク)では、プロジェクトは2番目の部分で既に若干変更されていますが、問題は発生しません。



設置



2.0.2以上のRailsをインストールします

sphinx 0.9.8: www.sphinxsearch.com/downloads.htmlをダウンロードして自分で組み立てるか、ports / portages / <必要なものを挿入>を使用してください

$ sudo port install sphinx







SphinxはMySQLとPostgreSQLの2つのサブデータベースをサポートしていますが、どのデータベースのサポートも簡単に取得できます。

インストール後の検証:

Macintosh:sphinx-0.9.8 kronos$ searchd -h

Sphinx 0.9.8-release (r1371)

Copyright (c) 2001-2008, Andrew Aksyonoff

...







searchdおよびindexerへのパスは、環境変数のパスに含まれている必要があります。



Sphinxはいくつかのユーティリティで構成されており、その一部は次のとおりです。

searchd-検索デーモン

検索は、デバッグ/テスト検索用のsearchdに対応するコンソールです。

インデクサーはインデクサーです。

プロジェクトを作成します。

$ rails sphinxtest -d mysql

$ cd sphinxtest/







config / database.ymlを編集することを忘れないでください



便宜上、プラグインを使用してスフィンクスを操作します。

Railsには、 ultrasphinxThinking Sphinxの 2つの適切なプラグインがあると思います (ちなみに、記事の執筆中にRailsCastが登場ました)。 後者は、内部命名のために別のプラグイン「redhill on rails」と競合するため、最初のプラグインを使用します。 しかし、おそらく2番目の方が優れています-自分で選択してください。 :)

プラグインのインストール:

$ script/plugin install git://github.com/fauna/ultrasphinx.git









カスタマイズ



$ mkdir config/ultrasphinx

cp vendor/plugins/ultrasphinx/examples/default.base config/ultrasphinx/







default.base-sphinx構成ファイルの場合は空白。 最初の部分では、単にログ/ pid /インデックスへのパスを設定します:

# ...

searchd

{

# ...

log = /opt/local/var/db/sphinx/log/searchd.log

query_log = /opt/local/var/db/sphinx/log/query.log

pid_file = /opt/local/var/db/sphinx/log/searchd.pid

# ...

}

# ...

index

{

#

path = /opt/local/var/db/sphinx/

# ...

}

# ...







コードを書く



簡単にするために、ajaxを使用して...アーティストを名前で検索するフォームを持つコントローラーを1つ作成します。 アーティストのモデルは1つのフィールドで構成されます-タイトル:

$ script/generate controller home index search

$ script/generate model artist







移行コード、アーティストにタイトルフィールドが1つだけあるようにします(db / migrate /..._ create_artists.rb):

クラスCreateArtists <ActiveRecord ::移行
   def self.up
     create_table:アーティストは| t |
       t.string:title ,: null => false
       t.timestamps
    終わり
  終わり

   def self.down
     drop_table:アーティスト
  終わり
終わり


ここで、1つのフィールド(app / models / artist.rb)で検索することをスフィンクスに伝えます:

class Artist < ActiveRecord::Base

is_indexed :fields => ['title']

end







エントリ「is_indexed:fields => ['title']」は、1つのフィールドでインデックス作成が行われることを意味します。



さて、データベースを作成し、移行を実行します。

$ rake db:create

$ rake db:migrate







config / routes.rbファイルでルートを設定することも価値があります。

map.root :controller => 'home'

map.search 'search', :conditions => {:method => :get}, :controller => 'home', :action => 'search'









コントローラーコード(app / controllers / home_controller.rb):

クラスHomeController <ApplicationController
   defインデックス
  終わり

   def検索
     query = params [:query] .split(/ '([^'] +) '| "([^"] +) "| \ s + | \ + /)。reject {| x | x.empty?}。マップ{| x | x.inspect} * '&&'
     @artists = Ultrasphinx :: Search.new(:query => query、 
                                       :sort_mode => 'relevance'、 
                                       :class_names => ["アーティスト"])    
     @ Artists.run
     respond_to do |形式|
       format.js#search.js.erb
    終わり
  終わり
終わり


最初の正規表現では、検索クエリを解析し、単語をスペースに分割し、空の単語(たとえば、、、)を無視し、すべての単語に引用符を追加します。 操作&&は、クエリなどの単語のセットのみを意味します

「ブリードアウト」=>「ブリード」&&「it」&&「out」は、エントリ「Sell it out」(3つのうち2つの単語が一致)に対応します。 &&は必要な単語のリストを指示するのではなく、単にそれらをリストします(すべての単語の必須の存在が必要な場合は、ANDを使用する必要がありますが、第2部ではそれ以上です)。

パラメーターについて簡単に説明します。

:query-検索クエリ

:sort_mode-ソート結果のタイプ

:class_names-検索の結果として作成されるモデルクラス名の配列。 Sphinxは、各ドキュメントをフィールドとその値のセットとして内部的に保存します。 Railsでは、このような表現を使用することは便利ではありませんが、既製のモデルオブジェクトを使用する方がはるかに便利です。 Ultrasphinxは、見つかったドキュメントが属するモデルを判別し、そのインスタンスを作成します。そのため、検索自体はArtist.find(...)またはArtist.paginateと同じです(はい、検索結果はwill_paginateと互換性があります)。

@ Artists.runチームがリクエストを実行します。 リクエストは非常に高速です。 700万分の1ベース-1000分の1秒。

完成したプロジェクトでビュー(テンプレート)を表示できます



これで、データベースに何かを追加できます。

$ script/console

>> Artist.create(:title => 'Tiesto')

>> Artist.create(:title => 'Armin')

>> Artist.create(:title => 'ATB')

>> exit







プラグインが機能するために必要な準備をしましょう(is_indexed記述のモデルで何かを変更するたびにこれを行う必要があります):

$ rake ultrasphinx:configure

$ rake ultrasphinx:index

$ rake ultrasphinx:daemon:start ( restart )







開始してテスト)

$ mongrel_rails -p 3001 -d







小さいけれど



データベース内のデータを個別にインデックスします。 データベースにインデックスを削除/変更/追加すると、インデックスは変更されません。 ベースの変更がインデックスに影響を与えるために、ベースの完全なインデックス再作成:

$ rake ultrasphinx:index







もちろん、これはあまり良くありません。 しかし、問題の解決策が存在し、デルタインデックスと呼ばれることを保証できます。 次のパートでそれについて。

まとめ



スフィンクスは非常にクールなものです:)。 オープンソースの無料のスマートな検索とインデックス。 持っている必要があります!



アナログ



acts_as_ferretはアナログとして言及できますが、小規模なプロジェクトには理想的です(たとえば、 Hackfest Rambler使用しました)が、大量のデータの場合はそれほど重要ではない振る舞いをします。

post-tsearch2 tsearch2には、一見悪くないプラグインがあります。tsearch として機能し 、戦闘では使用しませんでした、わかりません。 Acts_as_solrがまだあります




All Articles