2016-09-27 3 views
0

В настоящее время я использую elasticsearch для поиска клиента по имени, он работает, если вы введете полное имя. Однако мне нужно иметь возможность искать, даже если клиент ввел только первые две буквы имени. Я пытаюсь использовать частичное совпадение, хотя я получаю эту ошибку.Частичные соответствия elasticsearch rails

AdGroup.__elasticsearch__.create_index! force:true 
[!!!] Index does not exist (Elasticsearch::Transport::Transport::Errors::NotFound) 
Elasticsearch::Transport::Transport::Errors::BadRequest: [400] {"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"analyzer on field 
[client_name] must be set when search_analyzer is 
set"}],"type":"mapper_parsing_exception","reason":"Failed to parse 
mapping [ad_group]: analyzer on field [client_name] must be set when 
search_analyzer is set","caused_by":{"type":"mapper_parsing_exception","reason":"analyzer on field [client_name] must be set when search_analyzer is set"}},"status":400} 

Мои модели/объявление-group.rb

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

settings analysis: { 
    filter: { 
    ngram_filter: { type: "nGram", min_gram: 2, max_gram: 12 } 
    }, 
    analyzer: { 
     index_ngram_analyzer: { 
      type: 'custom', 
      tokenizer: 'standard', 
      filter: ['lowercase', 'ngram_filter'] 
     }, 
     search_ngram_analyzer: { 
      type: 'custom', 
      tokenizer: 'standard', 
      filter: ['lowercase'] 
     } 
    } 
} do 
mapping do 
    indexes :published 
    indexes :client_name,:type => "string", index_analyzer: "index_ngram_analyzer", search_analyzer: "search_ngram_analyzer" 
    indexes :created_at 
    indexes :updated_at 
    indexes :preview_updated_at 
end 
end 

контроллер/ADGROUPS

class AdGroupsController < ApplicationController 
    def index 
     if params[:client_name] 
     @ad_groups = AdGroup.search(params[:client_name]).page(params[:page]).results 
     else 
      @ad_groups = AdGroup.includes(:client).where(is_template: false).paginate(:page => params[:page]).order('id DESC') 
     end 

    end 
end 

Любая идея, почему?

ответ

-1

Я не уверен, насколько это поможет, но мне пришлось иметь дело с этим для клиента, который хотел иметь возможность искать предприятия. Конечно, это было больше года назад, поэтому я не помню подробностей, но мне пришлось внести это изменение в business_profiles_controller.rb.

def index 
    if params[:query].present? 
    @business_profiles = BusinessProfile.search(params[:query], fields: [{ name: :word_middle }]) 
    else 
    @business_profiles = BusinessProfile.all 
    end 
end 

Флаг :word_middle позволил нам искать в :name поле для каждого бизнес-профиля.

Надеюсь, это помогло.

Using SearchKick and ElasticSearch in Rails 4

1

Проблема заключается в том, что вы определяете search_analyzer и index_analyzer, но не по умолчанию analyzer. Взгляните на documentation.

Это будет работать, если вы измените строку кода, где вы установили анализаторы для client_name в:

indexes :client_name,:type => "string", analyzer: "index_ngram_analyzer", search_analyzer: "search_ngram_analyzer" 

Таким образом, он будет принимать по умолчанию analyzer во время индекса, в то время как он будет забрать search_analyzer во время запроса.

+0

спасибо! Это решило эту проблему, хотя все еще не может заставить ее выполнить частичное совпадение. –

+0

Что вы используете для запросов? Не могли бы вы опубликовать свой метод? – davide

+0

Кстати, если вы хотите совпадение с первыми символами ввода, я бы лучше использовал фильтр 'edge_ngram'. См. Https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-edgengram-tokenizer.html – davide

Смежные вопросы