Как получить автозаполнение Solr во всей фразе, когда запрос содержит несколько терминов?

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

solar powered
solar glass
solar globe
solar lights
solar magic
solid brass
solid copper

Что я хочу:

  • Если я ищу sol, результат должен включать все эти значения. Это работает.
  • Если я ищу solar, я должен получить только первые пять. Это работает.
  • Если я ищу solar gl, я должен получить только solar glass и solar globe. Это не работает. Вместо этого я получаю один набор совпадений для solar и второй набор совпадений для gl.

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

Я (безуспешно) пытался:

  • Запрос с помощью "solar gl"
  • Запрос с помощью mm=100%
  • Определение отдельных анализаторов запросов и индексов с использованием KeywordTokenizerFactory. (Не знаю, что, черт возьми, я подумал, что будет.)
  • Определение анализатора индексов, но не анализатора запросов.
  • Определение анализатора запросов без токенизатора.

Здесь моя текущая схема:

<field name="suggest_phrase" type="suggest_phrase"
    indexed="true" stored="false" multiValued="false" />

И определение поля:

<fieldType name="suggest_phrase" class="solr.TextField" positionIncrementGap="100">
    <analyzer>
        <tokenizer class="solr.KeywordTokenizerFactory" />
        <filter class="solr.LowerCaseFilterFactory" />
    </analyzer>
</fieldType>

И config:

<searchComponent name="suggest_phrase" class="solr.SpellCheckComponent">
    <lst name="spellchecker">
        <str name="name">suggest_phrase</str>
        <str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
        <str name="lookupImpl">org.apache.solr.spelling.suggest.fst.FSTLookup</str>
        <str name="field">suggest_phrase</str>
        <str name="buildOnCommit">true</str>
    </lst>
</searchComponent>
<requestHandler class="org.apache.solr.handler.component.SearchHandler" name="/suggest_phrase">
    <lst name="defaults">
        <str name="spellcheck">true</str>
        <str name="spellcheck.dictionary">suggest_phrase</str>
        <str name="spellcheck.onlyMorePopular">true</str>
        <str name="spellcheck.count">10</str>
        <str name="spellcheck.collate">false</str>
    </lst>
    <arr name="components">
        <str>suggest_phrase</str>
    </arr>
</requestHandler>

Ответ 1

Нашел ответ, наконец! Я знал, что очень близко. Оказывается, моя конфигурация выше была правильной, и мне просто нужно было изменить свой запрос.

  • Используйте KeywordTokenizerFactory, чтобы строки индексировались в целом.
  • Используйте SpellCheckComponent для обработчика запросов.
  • Кусок, который я отсутствовал, не запрашивает с q=<string>, а с spellcheck.q=<string>.

Учитывая исходные строки, отмеченные выше, и запрос spellcheck.q=solar+gl, это дает желаемые результаты:

solar glass
solar globe

Ответ 2

Я пробовал это много раз, и я пришел к выводу, что это невозможно из коробки. Я нашел обходное решение для этого:

Я проиндексировал данные, добавляя суицидные символы между каждым словом, чтобы они не были обозначены. Например:

solarzzzzzzpowered
solarzzzzzzglass
solarzzzzzzglobe

то, когда вы составляете свой запрос, вы должны добавить то же количество символов между двумя введенными вами словами, например solr gl стать solarzzzzzzgl.

Это позволит добиться того, что вы просите.

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

Ответ 3

Вы можете использовать AnalyzingInfixLookupFactory или FreeTextLookupFactory

  • AnalyzingInfixLookupFactory возвращает все содержимое поля.
  • FreeTextLookupFactory возвращает определенное количество токенов.

Более подробные сведения и другие алгоритмы для инспекторов вы найдете здесь: http://alexbenedetti.blogspot.de/2015/07/solr-you-complete-me.html

Конфигурация Solr

<lst name="suggester">
  <str name="name">AnalyzingInfixSuggester</str>
  <str name="lookupImpl">AnalyzingInfixLookupFactory</str> 
  <str name="dictionaryImpl">DocumentDictionaryFactory</str>
  <str name="field">title</str>
  <str name="weightField">price</str>
  <str name="suggestAnalyzerFieldType">text_en</str>
</lst>

<lst name="suggester">
  <str name="name">FreeTextSuggester</str>
  <str name="lookupImpl">FreeTextLookupFactory</str> 
  <str name="dictionaryImpl">DocumentDictionaryFactory</str>
  <str name="field">title</str>
  <str name="ngrams">3</str>
  <str name="separator"> </str>
  <str name="suggestFreeTextAnalyzerFieldType">text_general</str>
</lst>