Solr: поиск с / без пробелов в ключевых словах

#web #search #solr

#веб #Поиск #solr

Вопрос:

Я сталкиваюсь с проблемой, когда пробелы вводятся в ключевые слова, например:

  • У нас есть продукт с названием «Sony Playstation 4 Camera V2 PS4 (PSVR)».
  • Поиск «playstation» или «playstation camera» возвращает этот продукт
  • Поиск «play station» или «play station camera» не возвращает этот продукт (обратите внимание на пробел)

Вот используемый тип поля:

     <fieldType name="text_en_splitting" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
        <analyzer type="index">
            <tokenizer class="solr.WhitespaceTokenizerFactory"/>
            <filter class="solr.HyphenatedWordsFilterFactory"/>
            <filter class="solr.EnglishMinimalStemFilterFactory"/>
            <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt"/>
            <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
            <filter class="solr.WordDelimiterGraphFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" preserveOriginal="1"/>
            <filter class="solr.LowerCaseFilterFactory"/>
        </analyzer>
        <analyzer type="query">
            <tokenizer class="solr.WhitespaceTokenizerFactory"/>
            <filter class="solr.HyphenatedWordsFilterFactory"/>
            <filter class="solr.EnglishMinimalStemFilterFactory"/>
            <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt"/>
            <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
            <filter class="solr.WordDelimiterGraphFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" preserveOriginal="1"/>
            <filter class="solr.LowerCaseFilterFactory"/>
        </analyzer>
    </fieldType>
 

Как я могу это исправить и сопоставить «playstation» и «play station»? Это ограничено только PlayStation для моего примера, но это может произойти с любым поисковым запросом, например, «киберпанк», «киберпанк». Таким образом, решения, требующие много ручной работы, такие как добавление синонима для play station => playstation , неосуществимы.

Вещи, которые я пробовал, но не смог заставить работать:

  • N-граммовый фильтр и токенизатор
  • Нечеткий поиск
  • Удаление пробелов
  • Экранирование пробелов

Ответ №1:

Вы можете использовать фильтр Shingle для объединения нескольких токенов в один.

 <analyzer type="query">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.HyphenatedWordsFilterFactory"/>
    <filter class="solr.EnglishMinimalStemFilterFactory"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt"/>
    <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.WordDelimiterGraphFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" preserveOriginal="1"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.ShingleFilterFactory"/>
</analyzer>
 

Если вы предполагаете, что термины написаны правильно при индексации, вы можете применить это только при запросе. Он объединит токены для вас, эффективно предоставляя вам несколько «объединенных» токенов:

 play station camera => play, station, camera, playstation, stationcamera
 

.. дано maxShingleSize=2 . Если вы увеличите максимальный размер до 3, это также даст вам playstationcamera один токен (в данном случае). Если у вас есть термины, в которых люди, возможно, разделяют слово несколько раз, это может быть необходимо.

Если вы предполагаете, что ваши термины проиндексированы правильно, а это необходимо только во время запроса, ваш индекс не изменится, и вам не придется переиндексировать (и размер не изменится).

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

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

1. Спасибо за вашу помощь! Это самая эффективная вещь, которую я пробовал до сих пор, с немного более точной настройкой она должна решить мою проблему.