2013-03-12 1 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 

И, допустим, у меня есть автомобиль под названием «Форд», и я обновляю свой индекс. Теперь, если я ищу «Форда»:

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

Моя машина в моих результатах. Теперь, если я ищу «For»:

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

Моя машина больше не найдена. Я думал, что фильтр nGram автоматически позаботится об этом для меня, но, видимо, это не так. В качестве временного решения я использую подстановочный знак (*) для таких поисков, но это определенно не лучший подход, являющийся ключевыми элементами определения min_gram и max_gram в моем поиске. Может ли кто-нибудь сказать мне, как они решили это?

Я использую Rails 3.2.12 с ruby ​​1.9.3. Версия ElasticSearch - 0.20.5.

ответ

5

Вы хотите использовать собственный анализатор вместо снежный ком один: Elasticsearch custom analyzer

В основном другие анализаторы поставляются с предопределенным набором фильтров и tokenizers.

Возможно, вы также хотите использовать фильтр Edge-Ngram: Edge-Ngram filter

Разница между Edge-Ngram и Ngram в основном Edge-Ngram в основном только торчащий на «краях» термина. Так начинается с фронта или сзади. Форд -> [Для] вместо -> [Для Орд]

Некоторые более продвинутые ссылки на тему автозавершения:

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

Another useful question with links provided

Edit

В принципе, у меня очень похожая настройка на то, что у вас есть. Но с другим анализатором для названия и многополюсного для обоих. И из-за многоязыковой поддержки здесь представлен массив имен, а не просто имя.

Я также указываю 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

+0

Да, я использую шины и рубины. Вы переиндексировали свои данные с помощью шины рейка: import CLASS = 'Car' FORCE = true? –

+0

Я сделал. Оба используют задачу рейка и удаляют/создают/импортируют непосредственно в консоли. – ChuckE