ElasticSearch, searching in the parent class using the globalization model and elastic search

I use this library to implement elasticsearch using the globalize model.

I have an Author class that contains many articles. Now I have an attribute in the author class called type_string, with which I want to search all articles. This is what my models look like.

Articles.rb

require 'elasticsearch/model'

class Article < ActiveRecord::Base

  translates :title, :text
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks
  include Elasticsearch::Model::Globalize::MultipleFields
  index_name 'relation_test'

  belongs_to :author

  after_commit on: [:create] do
    __elasticsearch__.index_document
  end

  after_commit on: [:update] do
    __elasticsearch__.index_document
  end

  after_commit on: [:destroy] do
    __elasticsearch__.delete_document
  end


  mapping _parent: { type: 'author' } do

    indexes :id,              type: 'integer'
    indexes :title_de,        analyzer: 'german'
    indexes :title_en,        analyzer: 'english'
    indexes :text_de,         analyzer: 'german'
    indexes :text_en,         analyzer: 'english'

  end

  def self.create_index!(options={})
    client = Author.__elasticsearch__.client
    client.indices.delete index: index_name rescue nil if options[:force]

    settings = Author.settings.to_hash.merge Article.settings.to_hash
    mappings = Author.mappings.to_hash.merge Article.mappings.to_hash

    client.indices.create index: index_name,
                          body:
                          {
                            settings: settings.to_hash,
                            mappings: mappings.to_hash 
                          }
  end

  after_commit lambda { __elasticsearch__.index_document(parent: author_id)  },  on: :create
  after_commit lambda { __elasticsearch__.update_document(parent: author_id) },  on: :update
  after_commit lambda { __elasticsearch__.delete_document(parent: author_id) },  on: :destroy

  def as_indexed_json(options={})
    self.as_json({ 
      only: [:title, :text],
      include: {
        author: { only: [:type_string] },
      }
     })
  end
end

Article.import # for auto sync model with elastic search

Authors.rb

class Author < ActiveRecord::Base

    translates :name, :type_string
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks
  include Elasticsearch::Model::Globalize::MultipleFields

  mapping do
    indexes :id,                     type: 'integer'
    indexes :type_string_de,         analyzer: 'german'
    indexes :type_string_en,         analyzer: 'english'
  end

  after_commit on: [:create] do
    __elasticsearch__.index_document
  end

  after_commit on: [:update] do
    __elasticsearch__.index_document
  end

  after_commit on: [:destroy] do
    __elasticsearch__.delete_document
  end


  def as_indexed_json(options={})
    { 
      author_id: author_id,
      type_string_de: type_string_de,
      type_string_en: type_string_en 
    }
  end

end

Here my seeds.rb

I18n.locale = :de

auth1 = Author.create!({ name: "Author1" , type_string: "Tanzer"})
auth2 = Author.create!({ name: "Author2" , type_string: "Laufer"})

Article.create!({ title: "Coffee", text: "killer thing to drink", author: auth1 })
Article.create!({ title: "Tea", text: "don't drink this is shit", author: auth2 })

And I get the following index conversion based on the articles object.

enter image description here

Although it shows me the identifier for the author object, but I cannot figure out how to get the authors.

So, in the finale, I want that if I look for the text "Tanzer", he brings me the author with type_String = "Tanzer"and his articles.

, , 0 .

a = Article.search({query:{has_parent:{parent_type:"author",query:{ match:{ type_string:"Tanzer"}}}}})
a.results.total # <== this gives 0.

Update:

include Elasticsearch::Model::Globalize::MultipleFields , _de and _en . .

+4

Source: https://habr.com/ru/post/1627014/


All Articles