2016-09-27 115 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 

控制器/广告组

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_analyzerindex_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