Less is Best

rubyが好き。技術の話とスタートアップに興味があります。

sunspot_railsを使用した全文検索エンジンのサンプル

RailsApache Solrを使用してアプリに全文検索機能を実装する。そんな検索エンジンをつかったサービスの開発を考えているので、ちょっとテストをしてみる。

rails new sunspot_sample

Gemfile

+gem 'sunspot_rails'
+gem 'nifty-generators'
+group :development do
+  gem 'sunspot_solr'
+end
bundle install

sunspot-solrのバグがあるらしいので、Rakefileにtaskを読み込んでおくことで、rakeの仕様が可能になる

Rakefile

# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require File.expand_path('../config/application', __FILE__)
require 'sunspot/solr/tasks'

SunspotSample::Application.load_tasks
rake sunspot:solr:start

でsolrを起動。終了する際は rake sunspot:solr:stop

モデルをsearchableにする

class Article < ActiveRecord::Base
  has_many :comments


  searchable do
    text :name, :content
  end
end

インデクシング

Railsアプリを軽く作成してダミーデータを入れておく。。。

rake db:fixture:load

その後に、データベースのカラムをインデクシングする

rake sunspot:reindex

全文検索機能をつける

検索窓を追加

<%= form_tag articles_path, :method => :get do %>
  <p>
    <%= text_field_tag :search, params[:search] %>
    <%= submit_tag "Search", :name => nil %>
  </p>
<% end %>

検索を行うようにする

  # GET /articles
  # GET /articles.json
  def index
    @search = Article.search do
      fulltext params['search']
    end
    @articles = @search.results
  end

さらに複雑に検索可能にする くわしくはここ

class Article < ActiveRecord::Base
  has_many :comments


  searchable do
    text :name, boost:5 #define full text search attribute 5倍重要にする
    text :content, :publish_month #月で検索可能にする(June,July)
    #コメントのcontentを検索可能にする
    text :comments do
      comments.map(&:content)
    end
  end

  def publish_month
    published_at.strftime('%B %Y')
  end
end

facetを用いた検索

class Article < ActiveRecord::Base
  has_many :comments


  searchable do
    text :name, boost:5 #define full text search attribute 5倍重要にする
    text :content, :publish_month #月で検索可能にする(June,July)
    #コメントのcontentを検索可能にする
    text :comments do
      comments.map(&:content)
    end
    #time :published_at
+   string :publish_month
  end

  def publish_month
    published_at.strftime("%B %Y")
  end
end
  # GET /articles
  # GET /articles.json
  def index
    @search = Article.search do
      fulltext params['search']
      #with(:published_at).less_than Time.zone.now
      facet :publish_month
      with(:publish_month,params[:month]) if params[:month].present?
    end
    @articles = @search.results
  end
<div id="facets">
  <h3>Published</h3>
  <ul>
    <% for row in @search.facet(:publish_month).rows %>
      <li>
        <% if params[:month].blank? %>
          <%= link_to row.value, :month => row.value %> (<%= row.count %>)
        <% else %>
          <strong><%= row.value %></strong> (<%= link_to "remove", :month => nil %>)
        <% end %>
      </li>
    <% end %>
  </ul>
</div>
rake sunspot:reindex

からのブラウザへアクセス(localhost:3000)すると絞込み検索を掛けることができる

本番環境ではsunspot-solrではなく、solrをしっかりとインストールして動かすようにすればいいはずです。