railsにおけるElasticsearchのクライアントTire構成

5488 ワード

$ gem install tire   ||   https://github.com/karmi/retire
#ロード#ロード#
#model tire  
class Article < ActiveRecord::Base
         include Tire::Model::Search
         include Tire::Model::Callbacks
end

#インデックスの名前
 index_name"#{Tire::Model::Search.index_prefix}<モデル名>"
 
#インデックスの作成
  class Article < ActiveRecord::Base
      include Tire::Model::Search
      include Tire::Model::Callbacks

      mapping do
        indexes :id,           :index    => :not_analyzed
        indexes :title,        :analyzer => 'snowball', :boost => 100
        indexes :content,      :analyzer => 'snowball'
        indexes :content_size, :as       => 'content.size'
        indexes :author,       :analyzer => 'keyword'
        indexes :published_on, :type => 'date', :include_in_all => false
      end
    end

# analyzer: 【keyword,snowball…】  type: 【string, integer, date ...】 boost: 

 
#jsonの作成
class Article < ActiveRecord::Base
      #   
    def to_indexed_json
        names      = author.split(/\W/)
        last_name  = names.pop
        first_name = names.join

        {
          :title   => title,
          :content => content,
          :author  => {
            :first_name => first_name,
            :last_name  => last_name
          }
        }.to_json
      end
    end

#...  
def is_admin? do
 ...
end

def to_indexed_json
    to_json(
        include: {:user{methods: [:is_admin?]}})
end

 
#インデックスの更新
 
    class Article < ActiveRecord::Base
      include Tire::Model::Search

      after_save do
        update_index if state == 'published'
      end
    end

 
#検索jsonデータの構築
…… 
#  , 
DEFAULT_QUERY_FIELDS = ['title','des']
def self.search(params)  
    # page: ,per_page: , highlight: 
    # load: elasticsearch json,  _source  fields  JSON , true   {include: user}, 
    tire.search(:page => (params[:page] || 1), per_page: 10, highlight: :name, load: true) do
   #  
      query do
     #  
        boolean do
          term 
          must { term 'is_admin?', true }        
          must { string (params[:q] || '*'), default_operator: "AND", fields: DEFAULT_QUERY_FIELDS }
        end
      end
     # terms [...],  
      filter :terms, 'tags' => ['ruby', 'java'] 
      ## range  
      filter :range, 'price' => {gte: 1}
      filter :range, 'price' => {lte: 2}

     #  
     facet 'global-tags', :global => true do
        terms :tags
     end
     #  (  type:date)
      sort { by 'created_at', "desc" }
    end
  end

……

 
 :
String: 
Integer: 
Long: 
Float: 
Double: 
Boolean: 

 :
Array: 
Object: 
Nested:  
multi_field 。 multi_field :"properties": { "created": { "type":"multi_field", "fields": { "created": { "type": "string" }, "date": { "type": "date"}}}}

 
     filter :nested, {path: 'cars'}.merge({query: (
      Tire::Search::Query.new do
        filtered do
          query { all }
          filter :range, 'cars.price' => {gte: params[:price_from].to_i} if params[:price_from].present?
          filter :range, 'cars.price' => {lte: params[:price_to].to_i} if params[:price_to].present?
        end
      end).to_hash}) if params[:price_from].blank? && params[:price_to]

 
tireインデックスの削除(このインデックスのデータは削除されました)
def self.date_authen!(klass, result)
    begin
      result.results
    rescue ActiveRecord::RecordNotFound => ex
      index_ids = ex.message.split('(')[1].to_s.split(')')[0].to_s.split(',').map(&:to_i)
      kass_ids = klass.where(id: index_ids).select(:id).map(&:id)
      delete_ids = index_ids - kass_ids
      delete_ids.each do |id|
        klass.tire.index.remove(klass.name.tableize.singularize, id)
      end
      klass.tire.index.refresh
    end
    result
  end

 
 
 Nested  http://www.elasticsearch.org/blog/managing-relations-inside-elasticsearch/
 
indexの表示:sudo./bin/plugin -install mobz/elasticsearch-head