简体   繁体   中英

Elasticsearch Rails indexing issue

I am using Elasticsearch and the Elasticsearch Rails gem. I have two models that are associated via ActiveRecord and I am trying to index and search them with Elasticsearch.

Here is my store model

store.rb

has_many :addresses
has_many :jobs

def as_indexed_json
  self.as_json(include: {
    customer: { include: { addresses: {}, jobs: {} } },
    vendors: {}
  })
end

settings index: { number_of_shards: 1 } do
  mapping dynamic: 'false' do
    indexes :id
    indexes :store_number
    indexes :manager
    indexes :customer do
      indexes :first_name
      indexes :addresses do
        indexes :city
        indexes :state
      end
      indexes :jobs do
        indexes :job_number
      end
    end
  end
end

here is my address model:

def as_indexed_json

end

settings index: { number_of_shards: 1 } do
  mapping dynamic: 'false' do
    indexes :city
    indexes :state
  end
end

I am also using Searchkit as my front end UI. Searchkit is able to aggregate and display all of the attributes that are in the store model (store number and manager for example). However, it is not able to view the nested items. In other words I cannot aggregate and retrieve the job_numbers under jobs which is under customer. I am able to view the customers name, etc. I have tried using type: "nested" next to jobs and all the other objects, but that doesn't make a difference. I have tried adjusting the as_indexed_json without any luck as well. Any one have any idea on this? I am stumped on this one.

try changing your as_indexed_json method to this:

def as_indexed_json() {
  hash = self.as_json()
  hash['jobs'] = self.jobs.map(&:job_number)
  hash['address_state'] = self.addresses.map(&:state)
  hash['address_city'] = self.addresses.map(&:city)
  hash
}

override the search in your store model like this:

def self.search(query)
  @search_definition = {
    query: {}
  }
  unless query.blank?
   @search_definition[:query] = {
     bool: {
       should: [
         {
           multi_match: {
             query: query,
             fields: ['store_number', 'manager', 'jobs', 'address_state', 'address_city'],
             operator: 'and'
           }
         }
       ]
     }
   }
  else 
    @search_definition[:query] = { match_all: {} }
  end
   __elasticsearch__.search(@search_definition)
end

You also need to changing the mapping settings to look like this:

settings index: { number_of_shards: 1 } do
  mapping do
   indexes :store_number, analyzer: 'keyword'
   indexes :jobs, analyzer: 'keyword'
   indexes :address_state, analyzer: 'keyword'
   indexes :address_city, analyzer: 'keyword'
   indexes :manager, type: 'multi_field' do 
          indexes :manager, analyzer: 'snowball'
          indexes :tokenized, analyzer: 'simple' 
   end
  end
end

These settings for the index are just examples. You can use different types , analyzers and tokenizers that best serves your use case.

With this you will get results when you search a store by it's indexed fields and also with job_number , city and also state , Although if you want to use the associations as filters, the search method and the mapping will be different.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM