Работают ли вместе stemming и нечеткий поиск в Apache Solr

#solr #stemming #fuzzy #porter-stemmer

#solr #stemming #нечеткий #porter-stemmer

Вопрос:

Я использую фабрику фильтров porter для поля, в котором содержится от 3 до 4 слов.

Например: «ABC BLOSSOM COMPANY»

Я также ожидаю получить вышеупомянутый документ при поиске ABC BLOSSOMING COMPANY.

Когда я запрашиваю это:

 name:ABC AND name:BLOSSOMING AND name:COMPANY
  

я получаю свой результат

Вот как выглядит проанализированный запрос

имя:southern имя:blossom имя: compani (Stemmer работает нормально)

Но когда я добавляю нечеткий синтаксис и запрос, подобный этому,

 name:ABC~1 AND name:BLOSSOMING~1 AND name:COMPANY~1
  

поиск не выдает никаких документов в качестве результата, и проанализированный запрос выглядит следующим образом

название:abc~1 название:blossoming~ 1 название:company~2

Это ясно показывает, что stemming не происходит. Пожалуйста, просмотрите и оставьте отзыв.

Комментарии:

1. Я подозреваю, что проблема в том, что вам нужно заключить термины вашего запроса в кавычки, чтобы Solr мог их правильно проанализировать. Попробуйте с name:"abc"~1 name:"blossoming"~1 name:"company"~2

2. Нечеткий синтаксис не позволяет заключать значения в кавычки, я пробовал, нечеткий поиск не будет работать

3. Пожалуйста, опубликуйте свой анализатор, если вам нужна дополнительная помощь в выборе фильтров / токенизаторов.

Ответ №1:

TL; DR
Stemming не происходит, поскольку вы использовали PorterFilter, который не является многокомпонентным.

Что делать?
Используйте один из фильтров / нормализаторов, который реализует многокомпонентный интерфейс MultiTermAwareComponent.

Объяснение
Вы, как и многие другие, попали в ловушку многовариантного поведения Solr и Lucense. В Solr wiki есть хорошая статья на эту тему. Несмотря на то, что эта статья устарела, она по-прежнему актуальна

Одним из сюрпризов для большинства пользователей Solr является то, что запросы с подстановочными знаками не проходили никакого анализа. Практически это означает, что запросы с подстановочными знаками (а также с префиксом и диапазоном) чувствительны к регистру, что противоречит ожиданиям. Начиная с этих SOLR-2438, SOLR-2918 и, возможно, SOLR-2921, это поведение изменено.

Что такое multiterm, о котором вы спрашиваете? По сути, это любой термин, который может «указывать» более чем на один реальный термин. Например, run * может расширяться до runs, runner, running, runt и т.д. Аналогично, запрос диапазона на самом деле также является «многострочным» запросом. До Solr 3.6 они были полностью необработанными, прикладному уровню обычно приходилось применять любые требуемые преобразования, например, вводить данные в нижнем регистре. Запуск этих типов терминов через «обычную» цепочку анализа запросов приводит ко всевозможным интересным поведениям, поэтому их удалось избежать.

Комментарии:

1. Я просмотрел список фильтров с несколькими терминами, ни один из них не предлагает stemming, и мне конкретно нужен stemming. Думаю, в этом случае мне придется выбирать между fuzzy и stemming.

Ответ №2:

Что ж, вот конфигурация, которая в какой-то степени сделала это за меня, пока я экспериментировал:

 <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100" multiValued="true">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.FlattenGraphFilterFactory"/>        
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
    <filter class="solr.LowerCaseFilterFactory"/>
     <filter class="solr.PorterStemFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
    <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
     <filter class="solr.PorterStemFilterFactory"/>
  </analyzer>
</fieldType>
  

(да, я изменил существующее поле «text_general», я сказал, что экспериментирую)

Используя его с расстоянием нечеткого редактирования 2, он дал следующие результаты для термина «пренебрежение»:

 1. Lost in Translation - A faded movie star and a neglected young woman...
2. Election - A high school teacher meets his match in an over-achieving...
3. Annie Hall - Alvy Singer, a divorced Jewish comedian, reflects on his relationship...
  

Что в некоторой степени хорошо, потому что первый результат подходит.

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

 1. The Searchers - ... a years-long journey to rescue his niece from ...
2. Star Wars - ...while also attempting to rescue Princess Leia from...
  

Итак, результаты fuzzy stemming довольно противоречивы. Elasticsearch, который, как и SOLR, основан на Lucene, не рекомендует использовать fuzzy с stemming:

Это также означает, что при использовании, скажем, анализатора snowball нечеткий поиск «running» будет сведен к «run», но не будет соответствовать написанному с ошибкой слову «runninga», которое происходит от «runninga», потому что «run» находится более чем в 2 правках от «runninga». Это может вызвать некоторую путаницу, и по этой причине часто имеет смысл использовать simple analyzer только для текста, предназначенного для использования с нечеткими запросами, возможно, также отключая синонимы.

Источник:https://www.elastic.co/blog/found-fuzzy-search