6

I have a Post model:

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

I have 1 model, 2 very different functions which need a completely different index.

How can I build 2 different indices in 1 model and tell the __elasticsearch__.search which index it should use ?

2 Answers 2

2

You know you can use 2 models for the same database table right? I'd use a concern for the shared methods and one model per index, that or 3 models, one for regular use and the 2 others specifically for the indexes. It might feel like a hack at first but that might be a cleaner solution in the end. Let me know how it goes :p

Sign up to request clarification or add additional context in comments.

Comments

1

Although a bit late, I came across this question when trying to find a solution for the same problem. In my case I needed multilanguage support for a model and elasticsearch.

In config/initializers/elasticsearch.rb we override __type_for_hit to avoid index_name matching

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

Then in our Model

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  

mappings allows us to create indexes like:

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

Then, in order to import documents:

Post.import index:'posts-en'

Notice that you can define mappings as a function and create as many different indexes as you want. Finally you can search across an index or multiple indexes like:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.