2013-01-18 28 views
6

Tôi có một ứng dụng Rails được thiết lập với ElasticSearch và Tyre để tìm kiếm trên một mô hình và tôi đã tự hỏi làm thế nào tôi nên thiết lập ứng dụng của tôi để làm chuỗi mờ khớp với một số chỉ mục nhất định trong mô hình. Tôi có mô hình của tôi thiết lập để lập chỉ mục về những thứ như tiêu đề, mô tả, vv nhưng tôi muốn làm phù hợp chuỗi mờ trên một số trong những người và tôi không chắc chắn nơi để làm điều này tại. Tôi sẽ bao gồm mã của tôi dưới đây nếu bạn muốn bình luận! Cảm ơn!Chuỗi mờ phù hợp với Rails (Tire) và ElasticSearch

Trong bộ điều khiển:

def search 
     @resource = Resource.search(params[:q], :page => (params[:page] || 1), 
           :per_page =>15, load: true) 
    end 

Trong Model:

class Resource < ActiveRecord::Base 
    include Tire::Model::Search 
    include Tire::Model::Callbacks 

    belongs_to :user 
    has_many :resource_views, :class_name => 'UserResourceView' 

    has_reputation :votes, source: :user, aggregated_by: :sum 

    attr_accessible :title, :description, :link, :tag_list, :user_id, :youtubeID 
    acts_as_taggable 

    mapping do 
     indexes :id, :index => :not_analyzed 
     indexes :title, :analyzer => 'snowball', :boost => 40 
     indexes :tag_list, :analyzer => 'snowball', :boost => 8 
     indexes :description, :analyzer => 'snowball', :boost => 2 
     indexes :user_id, :analyzer => 'snowball' 
    end 
end 

Trả lời

2

Hãy thử tạo máy phân tích tùy chỉnh để đạt được tính năng bắt nguồn khác, vv Kiểm tra ví dụ của tôi (ví dụ này cũng sử dụng Mongoid & đính kèm, đừng nhìn vào nó nếu bạn không cần nó):

class Document 
     include Mongoid::Document 
     include Mongoid::Timestamps 
     include Tire::Model::Search 
     include Tire::Model::Callbacks 

     field :filename, type: String 
     field :md5, type: String 
     field :tags, type: String 
     field :size, type: String 

     index({md5: 1}, {unique: true}) 
     validates_uniqueness_of :md5 


     DEFAULT_PAGE_SIZE = 10 

     settings :analysis => { 
      :filter => { 
       :ngram_filter => { 
        :type => "edgeNGram", 
        :min_gram => 2, 
        :max_gram => 12 
       }, 
       :custom_word_delimiter => { 
        :type => "word_delimiter", 
        :preserve_original => "true", 
        :catenate_all => "true", 
       } 
      }, :analyzer => { 
       :index_ngram_analyzer => { 
        :type => "custom", 
        :tokenizer => "standard", 
        :filter => ["lowercase", "ngram_filter", "asciifolding", "custom_word_delimiter"] 
       }, 
       :search_ngram_analyzer => { 
        :type => "custom", 
        :tokenizer => "standard", 
        :filter => ["standard", "lowercase", "ngram_filter", "custom_word_delimiter"] 
       }, 
       :suggestions => { 
        :tokenizer => "standard", 
        :filter => ["suggestions_shingle"] 
       } 
      } 
     } do 
     mapping { 
      indexes :id, index: :not_analyzed 
      indexes :filename, :type => 'string', :store => 'yes', :boost => 100, :search_analyzer => :search_ngram_analyzer, :index_analyzer => :index_ngram_analyzer 
      indexes :tags, :type => 'string', :store => 'yes', :search_analyzer => :search_ngram_analyzer, :index_analyzer => :index_ngram_analyzer 
      indexes :attachment, :type => 'attachment', 
        :fields => { 
         :content_type => {:store => 'yes'}, 
         :author => {:store => 'yes', :analyzer => 'keyword'}, 
         :title => {:store => 'yes'}, 
         :attachment => {:term_vector => 'with_positions_offsets', :boost => 90, :store => 'yes', :search_analyzer => :search_ngram_analyzer, :index_analyzer => :index_ngram_analyzer}, 
         :date => {:store => 'yes'} 
        } 
     } 
     end 


     def to_indexed_json 
     self.to_json(:methods => [:attachment]) 
     end 

     def attachment   
      path_to_file = "#{Rails.application.config.document_library}#{path}/#{filename}" 
      Base64.encode64(open(path_to_file) { |file| file.read }) 
     end 

     def self.search(query, options) 
     tire.search do 
      query { string "#{query}", :default_operator => :AND, :default_field => 'attachment', :fields => ['filename', 'attachment', 'tags'] } 
      highlight :attachment 
      page = (options[:page] || 1).to_i 
      search_size = options[:per_page] || DEFAULT_PAGE_SIZE 
      from (page -1) * search_size 
      size search_size 
      sort { by :_score, :desc } 
      if (options[:facet]) 
      filter :terms, :tags => [options[:facet]] 
      facet 'global-tags', :global => true do 
       terms :tags 
      end 
      facet 'current-tags' do 
       terms :tags 
      end 
      end 
     end 
     end 
    end 

Hy vọng điều đó sẽ giúp ích,

+0

hữu ích, nhưng elasticsearch đã kết thúc quá cồng kềnh nên chúng tôi đã chuyển sang postgresql. cảm ơn mặc dù! – noname

+0

rất hữu ích ... với một chút kiên nhẫn, ví dụ ur làm việc như một nét duyên dáng :) – Rinku

+1

Tham số ': store => 'yes'' có hiệu lực gì? – phillbaker

Các vấn đề liên quan