2013-03-12 58 views
1

尽管我已经看到很多帐户提到这是相对直接的,但我还没有设法看到它正常工作。假设我有这个:ElasticSearch/Tire:如何正确设置部分单词搜索

class Car < ActiveRecord::Base 
    settings analysis: { 
    filter: { 
     ngram_filter: { type: "nGram", min_gram: 3, max_gram: 12 } 
    }, 
    analyzer: { 
     partial_analyzer: { 
     type: "snowball", 
     tokenizer: "standard", 
     filter: ["standard", "lowercase", "ngram_filter"] 
     } 
    } 
    } do 
    mapping do 
     indexes :name,     index_analyzer: "partial_analyzer" 
    end 
    end 
end 

假设我有一辆名为“Ford”的汽车,我更新了我的索引。现在,如果我搜索“福特”:

Car.tire.search { query { string "Ford" } } 

我的车在我的结果中。现在,如果我查找“For”:

Car.tire.search { query { string "For" } } 

我的车已找不到了。我认为nGram过滤器会自动为我处理,但显然不是。作为临时解决方案,我使用通配符(*)进行此类搜索,但这绝对不是最好的方法,因为我的搜索中是min_gram和max_gram定义的关键元素。谁能告诉我他们是如何解决这个问题的?

我使用Rails 3.2.12与红宝石1.9.3。 ElasticSearch版本为0.20.5。

回答

5

你想使用自定义的分析,而不是一个滚雪球的:Elasticsearch custom analyzer

基本上其他分析仪配备了一组预定义的过滤器和断词。

你可能也想使用边NGRAM过滤器:Edge-Ngram filter

边NGRAM和NG​​RAM之间的差别基本上是边NGRAM基本上只坚持了一个学期的“边缘”。所以它从前面或后面开始。福特 - > [供]代替 - > [供,ORD]

上自动完成的课题一些更高级的链接:

Autocompletion with fuzziness (pure elasticsearch, no tire, but very good read)

Another useful question with links provided

编辑

基本上我有一个非常类似的设置,你有什么。但是用另一个标题和多字段的分析器。由于多语言支持,这里有一个名称数组,而不是一个名称。

我还指定了search_analyzer,我使用了字符串键而不是符号。这是我实际上有:

settings "analysis" => { 
    "filter" => { 
     "name_ngrams" => { 
      "side"  => "front", 
      "max_gram" => 20, 
      "min_gram" => 2, 
      "type"  => "edgeNGram" 
     } 
    }, 
    "analyzer" => { 
     "full_name"  => { 
      "filter" => %w(standard lowercase asciifolding), 
      "type"  => "custom", 
      "tokenizer" => "letter" 
     }, 
     "partial_name"  => { 
      "filter" => %w(standard lowercase asciifolding name_ngrams), 
      "type"  => "custom", 
      "tokenizer" => "standard" 
     } 
    } 
} do 
    mapping do 
    indexes :names do 
     mapping do 
     indexes :name, :type => 'multi_field', 
       :fields => { 
        "partial"   => { 
         "search_analyzer" => "full_name", 
         "index_analyzer" => "partial_name", 
         "type"   => "string" 
        }, 
        "title"  => { 
         "type"  => "string", 
         "analyzer" => "full_name" 
        } 
       } 
     end 
    end 
    end 
end 
+0

我用你的定义(自定义分析,边缘正克过滤器),并产生相同的结果:“对于”什么回报,“福特”返回的一切。根据文件,它应该像你说的那样工作,我只是不明白为什么它不是。你在使用Ruby/Tire吗? – ChuckE 2013-03-12 16:55:04

+0

是的,我正在使用轮胎和红宝石。你是否用耙轮重新索引你的数据:import CLASS ='Car'FORCE = true? – 2013-03-13 09:23:24

+0

我做到了。都使用rake任务并直接在控制台中删除/创建/导入。 – ChuckE 2013-03-13 14:55:00