Токенизировать результат NGramFilterFactory в Solr (анализатор запросов) - PullRequest
3 голосов
/ 10 февраля 2012

Я использую NGramFilterFactory для индексации и запросов.

Так что, если я ищу "переполнение", он создает запрос, подобный этому:

mySearchField:"ov ve ... erflow overflo verflow overflow"

Но если я неправильно пишу«переполнение», то есть «owerflow», совпадений нет, потому что кавычки вокруг запроса:

mySearchField:"ow we ... erflow owerflo werflow owerflow"

Можно ли разбить результат на NGramFilteFactory, что он создаст запрос, подобный этому:

mySearchField:"ow"
mySearchField:"we"
mySearchField:"erflow"
mySearchField:"owerflo"
mySearchField:"werflow"
mySearchField:"owerflow"

В этом случае solr также найдет результаты, потому что токен "erflow" существует.

Ответы [ 2 ]

4 голосов
/ 10 февраля 2012

Вам не нужно маркировать ваш запрос, как вы написали.Проверьте, применяется ли в schema.xml NGramFilterFactory как во время индекса, так и во время запроса.Затем используемый вами синтаксический анализатор запросов имеет значение.С LuceneQParser вы получите результат, который вы ищете, но не с DisMax и eDisMax.

Я проверил запрос mySearchField:owerflow с eDisMax и debugQuery=on:

<str name="querystring">text:owerflow</str>
<str name="parsedquery">
+((text:o text:w text:e text:r text:f text:l text:o text:w text:ow text:we text:er text:rf text:fl text:lo text:ow text:owe text:wer text:erf text:rfl text:flo text:low text:ower text:werf text:erfl text:rflo text:flow text:owerf text:werfl text:erflo text:rflow text:owerfl text:werflo text:erflow text:owerflo text:werflow text:owerflow)~36)
</str>

Если вы посмотрите в конец сгенерированного запроса, вы увидите ~36, где 36это количество n-грамм, сгенерированных по вашему запросу.Вы не получаете никаких результатов из-за этого ~36, но вы можете изменить его с помощью параметра mm, который должен соответствовать минимуму.

Если вы измените запросдо mySearchField:owerflow&mm=1 или значения ниже 25, вы получите результат, который ищете.

Разница между этим и вашим ответом заключается в том, что при EdgeNGramFilterFactory инфиксном запросе, таком как mySearchField:werflow не делает 'не возвращает никакого результата, в отличие от NGramFilterFactory.

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

1 голос
/ 10 февраля 2012

ОК, я нашел быстрый и простой способ решения проблемы.

У fieldType есть необязательный атрибут autoGeneratePhraseQueries (по умолчанию = true). Если я установил для autoGeneratePhraseQueries значение false, все будет нормально.

Пояснение:

fieldType, используемый в schema.xml:

<fieldType name="edgytext" class="solr.TextField" autoGeneratePhraseQueries="false">
 <analyzer type="index">
   <tokenizer class="solr.KeywordTokenizerFactory"/>
   <filter class="solr.LowerCaseFilterFactory"/>
   <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="25" />
 </analyzer>
 <analyzer type="query">
   <tokenizer class="solr.WhiteSpaceTokenizerFactory"/>
   <filter class="solr.LowerCaseFilterFactory"/>
   <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="25" />
 </analyzer>
</fieldType>

Если вы индексируете слово «сюрприз», в индексе есть следующие токены:

с, су, сюр, сюрп, сюрприз, сюрприз, сюрприз, сюрприз

Если вы ищете "surpriese" (с орфографической ошибкой), solr создает следующие токены (соответствующие токены выделены жирным шрифтом):

с , су , сюр , сюрп , сюрприз , сюрпри, сюрприз, сюрприз, сюрприз

Реальный запрос, который будет создан, выглядит так:

mySearchField: s, mySearchField: su, mySearchField: sup .. и т. Д.

Но если вы установите autoGeneratePhraseQueries = true, будет создан следующий запрос:

mySearchField: "s su surp supr сюрприз сюрприз сюрприз"

Это запрос фразы, который не соответствует индексированным терминам.

...