Rails - ElasticSearch - 一个模型中的多个索引

时间:2015-03-01 00:52:50

标签: ruby-on-rails elasticsearch

我有一个Post模型:

class Post < ActiveRecord::Base
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks

  # I WANT THIS FUNCTION EXECUTED ON index1
  def self.search1(query)
      __elasticsearch__.search(
        {
        query:
        }
      )
  end

  # I WANT THIS FUNCTION EXECUTED ON index2
  def self.search2(query)
      __elasticsearch__.search(
        {
        query:
        }
      )
  end

  index_name  "index1" 

  # I NEED ANOTHER INDEX ? HOW CAN I DO ?  
  settings index1: { number_of_shards: 1 } do
    mappings dynamic: 'false' do
      indexes :title, analyzer: 'english'
    end
  end
end

Post.__elasticsearch__.client.indices.delete index: "index1" rescue nil
Post.__elasticsearch__.client.indices.create index: "index1", body: { settings: Post.settings.to_hash, mappings: Post.mappings.to_hash }
Post.import

我有1个模型,2个非常不同的函数需要完全不同的索引。

如何在1个模型中构建2个不同的索引并告诉__elasticsearch__.search它应该使用哪个索引?

2 个答案:

答案 0 :(得分:1)

您知道可以将2个模型用于同一个数据库表吗?我会使用共享方法的关注点和每个索引的一个模型,即3个模型,一个用于常规用途,另外两个用于索引。起初它可能感觉像是一个黑客,但最终可能是一个更清洁的解决方案。让我知道它是怎么回事:p

答案 1 :(得分:0)

虽然有点晚,但在尝试找到相同问题的解决方案时遇到了这个问题。在我的情况下,我需要为模型和Elasticsearch提供多语言支持。

在config / initializers / elasticsearch.rb中,我们重写__type_for_hit以避免index_name匹配

module Elasticsearch
  module Model
    module Adapter
      module Multiple
        module Records

          def __type_for_hit(hit)
            @@__types ||= {}

            @@__types[ "#{hit[:_index]}::#{hit[:_type]}" ] ||= begin
            Registry.all.detect do |model|
              model.document_type == hit[:_type]
            end
          end
        end
      end
   end
end

然后在我们的模型中

def self.mappings
  {
   :post => {
     :dynamic => "false",
     :properties => {
       :name => {
         :type          => "text",
         :analyzer      => "english"
        }
      }
    }
  }
end

class Elastic

   def initialize locale
      @locale = locale
   end

   def index_name
      "posts-" + @locale    
   end

   def document_type
      "post"
   end
end  

映射允许我们创建如下索引:

Post.__elasticsearch__.client.indices.create index: "posts-en", body: { mappings: Post.mappings.to_hash }

然后,为了导入文档:

Post.import index:'posts-en'

请注意,您可以将映射定义为一个函数,并根据需要创建尽可能多的不同索引。最后,您可以搜索一个或多个索引,例如:

Elasticsearch::Model.search('my_query', [Post::Elastic.new('en'), Post::Elastic.new('es') ]).records