#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. Спасибо за вашу помощь! Это самая эффективная вещь, которую я пробовал до сих пор, с немного более точной настройкой она должна решить мою проблему.