全文検索エンジンを使わずともActiveRecordに手軽に全文検索機能をつけるGemがありました。AttrSearchableというGemです。
さすがに一般的な全文検索エンジンと同じようにPDFやExcelファイルの中身まで検索することはできませんが、RDBに保存してあるテキストを検索するぐらいの用途には良いかもしれません。MySQLやPostgreSQLで対応している、全文検索用のインデックスにも対応しているので、通常のLIKE検索よりは良さそうです。
使い方
gem 'attr_searchable'をGemfileに追加して
bundle install`したあと、下のコードのように、ActiveRecordのモデルにattr_seachableというクラスマクロを追加します。
class Book < ActiveRecord::Base include AttrSearchable attr_searchable :title, :description, :stock, :price, :created_at, :available attr_searchable :comment => ["comments.title", "comments.message"] attr_searchable :author => "author.name" # ... has_many :comments belongs_to :author end
すると、こんな風に検索することができるようになります。
Book.search("stock > 0") # ... WHERE books.stock > 0 Book.search("price > 10 stock > 0") # ... WHERE books.price > 10 AND books.stock > 0 Book.search("Harry Potter") # ... WHERE (books.title LIKE '%Harry%' OR books.description LIKE '%Harry%' OR ...) AND (books.title LIKE '%Potter%' OR books.description LIKE '%Potter%' ...) Book.search("available:yes OR created_at:2014") # ... WHERE books.available = 1 OR (books.created_at >= '2014-01-01 00:00:00' and books.created_at <= '2014-12-31 00:00:00')
文字列検索の場合は自動的にカラムをまたいでLIKE検索してくれるようになるのが便利ですね。
RDBの全文検索機能を利用する場合
RDBの全文検索機能を利用する場合は、以下のコードのように、対象のカラムにtype: :fulltext
というオプションをつけます。
class Book < ActiveRecord::Base # ... attr_searchable_options :title, :type => :fulltext attr_searchable_options :author, :type => :fulltext # ... end
すると、クエリが以下のように変わります。
Book.search("Harry Potter") # MySQL: ... WHERE (MATCH(books.title) AGAINST('+Harry' IN BOOLEAN MODE) OR MATCH(books.author) AGAINST('+Harry' IN BOOLEAN MODE)) AND (MATCH(books.title) AGAINST ('+Potter' IN BOOLEAN MODE) OR MATCH(books.author) AGAINST('+Potter' IN BOOLEAN MODE)) # PostgreSQL: ... WHERE (to_tsvector('simple', books.title) @@ to_tsquery('simple', 'Harry') OR to_tsvector('simple', books.author) @@ to_tsquery('simple', 'Harry')) AND (to_tsvector('simple', books.title) @@ to_tsquery('simple', 'Potter') OR to_tsvector('simple', books.author) @@ to_tsquery('simple', 'Potter'))
2014/6/29現在でバージョンが0.0.3とかなり若いGemではありますが、かなり便利そうなので、ぜひ育っていって欲しいGemです。