Elasticsearch не работает должным образом

Я использую elasticsearch и globalize gems для полнотекстового поиска, и я ожидаю, что смогу искать имя поставщика, локализованное описание, используя чешский/английский анализатор.

Пример: Название поставщика: "Bonami.cz" Описание поставщика_CZ: "Описание теста на чешском языке".

Это работает, когда я ищу "Bonami.cz", но не работает (0 результатов), когда я ищу:

  • «Бонами» (часть слова)
  • "Описание теста)

Судя по документации, приведенные ниже методы должны работать, но, видимо, я что-то упустил. Я проверил индексы и данные в ElasticSearch.

Также мне нужно как-то установить чешский/английский анализатор, прежде чем использовать его в модели?

require 'elasticsearch/model'
require 'activerecord-import'

class Supplier < ActiveRecord::Base
    after_commit lambda { __elasticsearch__.index_document  },  on: :create
    after_commit lambda { __elasticsearch__.update_document },  on: :update

    translates :description, :fallbacks_for_empty_translations => true
    accepts_nested_attributes_for :translations

    include Elasticsearch::Model
    include Elasticsearch::Model::Callbacks
    include Elasticsearch::Model::Globalize::MultipleFields

        mapping do
          indexes :id,             type: 'integer'
          indexes :name,           analyzer: 'czech'
          indexes :description_ma, analyzer: 'czech'
          indexes :description_cs, analyzer: 'czech'
          indexes :description_en, analyzer: 'english'
       end

       def as_indexed_json(options={})
          { id: id,
            name: name,
            description_ma: description_ma,
            description_cs: description_cs,
            description_en: description_en    
         }
       end

       def self.search(query)
         __elasticsearch__.search(
            {
             query: {
               multi_match: {
                 query: query,
                 fields: ['name^10', 'description_ma', 'description_cs', 'description_en']
               }
            }
           })
       end
end

Любая идея, что не так? Спасибо, Мирослав

ОБНОВЛЕНИЕ 1 Меня вдохновило решение из Rails 4, elasticsearch-rails, но когда я пытаюсь искать сейчас, по любому слову я всегда получаю нулевой результат.

settings index: {
    number_of_shards: 1,
    analysis: {
      filter: {
        trigrams_filter: {
          type: 'ngram',
          min_gram: 2,
          max_gram: 10
        },
        content_filter: {
          type: 'ngram',
          min_gram: 4,
          max_gram: 20
        }
      },
      analyzer: {
        index_trigrams_analyzer: {
          type: 'custom',
          tokenizer: 'standard',
          filter: ['lowercase', 'trigrams_filter']
        },
        search_trigrams_analyzer: {
          type: 'custom',
          tokenizer: 'whitespace',
          filter: ['lowercase']
        },
        english: {
          tokenizer: 'standard',
          filter: ['standard', 'lowercase', 'content_filter']
        },
        czech: {
          tokenizer: 'standard',
          filter: ['standard','lowercase','content_filter']
        }
      }
    }
    } do
    mappings dynamic: 'false' do
      indexes :name, index_analyzer: 'index_trigrams_analyzer', search_analyzer: 'search_trigrams_analyzer'
      indexes :description_en, index_analyzer: 'english', search_analyzer: 'english'
      indexes :description_ma, index_analyzer: 'czech', search_analyzer: 'czech'
      indexes :description_cs, index_analyzer: 'czech', search_analyzer: 'czech'
    end
end

  def as_indexed_json(options={})
    { id: id,
      name: name,
      description_ma: description_ma,
      description_cs: description_cs,
      description_en: description_en    
    }
  end

   def self.search(query)
    __elasticsearch__.search(
      {
        query: {
          multi_match: {
            query: query,
            fields: ['name^10', 'description_ma', 'description_cs', 'description_en']
          }
        },
        highlight: {
          pre_tags: ['<em>'],
          post_tags: ['</em>'],
            fields: {
              name: {},
              description_ma: {},
              description_cs: {},
              description_en: {}
            }
        }
      }
    )
  end

Вот что я вижу, когда открываю эластичный URL-адрес поиска для данной модели:

{"suppliers":{"aliases":{},"mappings":{"supplier":    
{"dynamic":"false","properties":{"description_cs":      
{"type":"string","analyzer":"czech"},"description_en": 
{"type":"string","analyzer":"english"},"description_ma":
{"type":"string","analyzer":"czech"},"name":
{"type":"string","index_analyzer":"index_trigrams_analyzer","search_analyzer":"search_trigrams_analyzer"}}}},"settings":{"index":
{"creation_date":"1445797508427","analysis":{"filter":   
{"trigrams_filter":
{"type":"ngram","min_gram":"2","max_gram":"10"},"content_filter":
{"type":"ngram","min_gram":"4","max_gram":"20"}},"analyzer":{"english":
{"filter":["standard","lowercase","content_filter"],"tokenizer":"standard"},"index_trigrams_analyzer":{"type":"custom","filter":["lowercase","trigrams_filter"],"tokenizer":"standard"},"search_trigrams_analyzer":{"type":"custom","filter":["lowercase"],"tokenizer":"whitespace"},"czech":{"filter":["standard","lowercase","content_filter"],"tokenizer":"standard"}}},"number_of_shards":"1","number_of_replicas":"1","version": 
{"created":"1060099"},"uuid":"wX9kf3OQSva24Iwk7sZ8AQ"}},"warmers":{}}}

ОБНОВЛЕНИЕ 2

Не хватило двух шагов, чтобы все заработало как положено => 1. Повторно импортировать данные модели 2. Опечатка в именах полей описания (вместо description_ma/en/cs пришлось использовать ma/cs/en_description.

     settings index: {
    number_of_shards: 1,
     analysis: {
      filter: {
        trigrams_filter: {
          type: 'ngram',
          min_gram: 2,
          max_gram: 10
        },
        content_filter: {
          type: 'ngram',
          min_gram: 4,
          max_gram: 20
        }
      },
      analyzer: {
        index_trigrams_analyzer: {
          type: 'custom',
          tokenizer: 'standard',
          filter: ['lowercase', 'trigrams_filter']
        },
        search_trigrams_analyzer: {
          type: 'custom',
          tokenizer: 'whitespace',
          filter: ['lowercase']
        },
        english: {
          tokenizer: 'standard',
          filter: ['standard', 'lowercase', 'content_filter']
        },
        czech: {
          tokenizer: 'standard',
          filter: ['standard','lowercase','content_filter' ]
        }
      }
    }
    } do
    mappings dynamic: 'false' do
         indexes :name, index_analyzer: 'index_trigrams_analyzer', search_analyzer: 'search_trigrams_analyzer'
      indexes :en_description, index_analyzer: 'english', search_analyzer: 'english'
      indexes :ma_description, index_analyzer: 'czech', search_analyzer: 'czech'
      indexes :cs_description, index_analyzer: 'czech', search_analyzer: 'czech'
    end
   end

  def as_indexed_json(options={})
    { id: id,
      name: name,
      ma_description: ma_description,
      cs_description: cs_description,
      en_description: en_description    
    }
  end

   def self.search(query)
    __elasticsearch__.search(
      {
        query: {
          multi_match: {
            query: query,
            fields: ['name^10', 'ma_description', 'cs_description', 'en_description']
          }
        },
        highlight: {
          pre_tags: ['<em>'],
          post_tags: ['</em>'],
            fields: {
              name: {},
              ma_description: {},
              cs_description: {},
              en_description: {}
            }
        }
      }
    )
  end

person Miroslav    schedule 25.10.2015    source источник
comment
Вам нужно использовать анализатор ngram.   -  person eliasah    schedule 25.10.2015
comment
Спасибо @eliasah. Я обновил настройки в своем классе модели, см. ОБНОВЛЕНИЕ 1 выше, но теперь я получаю 0 результатов для любого слова, которое я пытаюсь найти. Наверное, я делаю какую-то фиктивную ошибку :/.   -  person Miroslav    schedule 25.10.2015
comment
Виноват. Я забыл повторно импортировать записи. Теперь я вижу, что могу искать и частичные строки. Что еще не работает, так это поиск в полях описания.   -  person Miroslav    schedule 25.10.2015
comment
Потому что вы еще не определили его для полей описания. Вам нужно будет установить это явно в отображении.   -  person eliasah    schedule 25.10.2015
comment
Он определяется как description_en, description_cs, description_ma, так как поле описания использует globalize gem. Также для этих полей создаются индексы, и я еще раз проверил данные в ElasticSearch. Есть ли другое место или другой способ, как это определить?   -  person Miroslav    schedule 25.10.2015
comment
Извините, я никогда в жизни не пользовался драгоценными камнями или рубинами, но я не могу найти, где вы определили анализаторы для своих полей описания.   -  person eliasah    schedule 25.10.2015
comment
Наконец-то я понял, в чем проблема, и вы очень хорошо меня туда направили. У меня там опечатка. Вместо description_en мне пришлось использовать en_description (то же самое для локалей cs и ma). Это решило проблему, и теперь все работает как положено. Еще раз спасибо за вашу помощь!   -  person Miroslav    schedule 25.10.2015


Ответы (1)


Чтобы иметь возможность выполнять поиск, который вы пытаетесь выполнить, вы должны использовать анализатор Ngram. (как обсуждалось в комментариях)

person eliasah    schedule 25.10.2015