Solr: объединение EdgeNGramFilterFactory и NGramFilterFactory - PullRequest
6 голосов
/ 30 августа 2011

У меня есть ситуация, когда мне нужно использовать EdgeNGramFilterFactory и NGramFilterFactory.

Я использую NGramFilterFactory для выполнения поиска в стиле «содержит» с минимальным количеством символов, равным 2. Я также хочу найти первую букву, например, «старт с помощью» переднего EdgeNGramFilterFactory.

Я не хочу понижать NGramFilterFactory до минимального числа символов 1, поскольку я не хочу индексировать все символы.

Некоторая помощь будет принята с благодарностью

Приветствия

Ответы [ 2 ]

7 голосов
/ 31 августа 2011

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

В следующем:

  • text содержит оригинальные токены, минимально обработанные;
  • text_ngram использует NGramFilter для ваших двухсимвольных токенов
  • text_first_letter использует EdgeNGram для односимвольных начальных букв токенов

Если вы обрабатываете все поля text таким способом, то вам, возможно, удастся избежать использования copyField для заполнения полей. В противном случае вы можете указать клиенту Solr отправлять в те же значения полей три разных типа полей.

При поиске включите все из них в свои поиски с параметром qf.

<fieldType name="text" class="solr.TextField" positionIncrementGap="100">
  <analyzer>
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StandardFilterFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

<fieldType name="text_ngram" class="solr.TextField" positionIncrementGap="100">
  <analyzer>
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StandardFilterFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
  </analyzer>
</fieldType>

<fieldType name="text_first_letter" class="solr.TextField" positionIncrementGap="100">
  <analyzer>
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StandardFilterFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="1" side="front"/>
  </analyzer>
</fieldType>

Настройка определений field и dynamicField остается за вами. Или дайте мне знать, если у вас есть дополнительные вопросы, и я могу отредактировать их с разъяснениями.

3 голосов
/ 30 августа 2011

Начните с применения EdgeNgramFilter с min = 1 и max = 1000 (мы хотим, чтобы весь оригинальный токен был включен). Пример:

hello => 'h', 'he', 'hel', 'hell', 'hello'

Во-вторых, используйте NGramFilter с min = 2. (я буду использовать 2 в качестве максимума в примере для простоты)

'h', 'he', 'hel', 'hell', 'hello' => 'h', 'he', 'he', 'el', 'he', 'el', 'll ',' он ',' el ',' ll ',' lo '

Теперь у вас будет несколько идентичных токенов, поскольку вы применили NGramFilter ко всем «частичным» токенам из EdgeNGramFilter, но просто примените RemoveDuplicatesTokensFilter, чтобы удалить их.

'h', 'он', 'он', 'el', 'он', 'el', 'll', 'он', 'el', 'll', 'lo' => 'h ',' он ',' el ',' ll ',' lo '

Теперь ваше поле будет поддерживать один запрос char "columns", а запрос "содержит несколько символов".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...