Изучите пользовательский запрос lucene.net после токенизации анализатора

Я использую Examine в Umbraco для запроса индекса узлов содержимого Lucene. У меня есть поле «completeNodeText», которое представляет собой объединение всех свойств узла (чтобы упростить задачу и не выполнять поиск по нескольким полям).

Я принимаю условия поиска, введенные пользователями. Когда поисковый запрос состоит из нескольких слов (например, «firstterm secondterm»), я хочу, чтобы результирующий запрос был запросом OR: верните мне результаты, где fullNodeText - firstterm OR secondterm.

Я хочу:

{+completeNodeText:"firstterm ? secondterm"}

но вместо этого я получаю:

{+completeNodeText:"firstterm secondterm"}

Если я ищу "firstterm OR secondterm" вместо "firstterm secondterm", то сгенерированный запрос будет правильным: {+completeNodeText:"firstterm ? secondterm"}

Я использую следующие вызовы API:

var searcher = ExamineManager.Instance.SearchProviderCollection["ExternalSearcher"];
var searchCriteria = searcher.CreateSearchCriteria();
var query = searchCriteria.Field("completeNodeText", term).Compile();

Есть ли простой способ заставить Examine генерировать этот запрос "ИЛИ"? Или мне нужно вручную создать необработанный запрос, вызвав StandardAnalyzer для токенизации пользовательского ввода и объединить запрос путем итерации по токенам? И в обход всего API-интерфейса Examine Fluent query?


person Tom Zahner    schedule 09.09.2013    source источник


Ответы (1)


Я не думаю, что этот вопросительный знак означает то, что вы думаете.

Похоже, вы создаете PhraseQuery, но вам нужны два непересекающихся TermQuery. В синтаксисе запроса Lucene фраза-запрос заключена в кавычки.

"firstterm secondterm"

Фразовый запрос ищет именно эту фразу, причем два термина появляются последовательно и по порядку. Размещение OR во фразе запроса не выполняет никакой логической логики, а обрабатывает ее как слово «ИЛИ». Знак вопроса - это заполнитель, используемый в PhraseQuery.toString() для представления удаленного стоп-слова (см. # Lucene-1396). Вы по-прежнему выполняете фразовый запрос, но теперь ожидается фраза из трех слов firstterm, за которой следует удаленное стоп-слово, за которым следует secondterm

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

 firstterm secondterm

Будет искать любой документ с любым из этих терминов (с более высокой оценкой документов с обоими).

person femtoRgon    schedule 09.09.2013
comment
Я не понимал, что это означало, что это фразовый запрос. Я предполагаю, что я хочу, чтобы Examine сгенерировало запрос, который представляет собой OR для каждого токена в исходном тексте, отправленном пользователем. - person Tom Zahner; 10.09.2013
comment
Но я хочу, чтобы Examine использовало StandardAnalyzer для токенизации всего, чтобы мне не приходилось вручную токенизировать вводимые пользователем данные (путем разделения на «и отфильтровывать стоп-слова»), а затем генерировать отдельные запросы поля ИЛИ для каждого из них, сгенерированных вручную. жетоны. Возможно ли, чтобы Examine / Lucene принимало поток токенов, а затем генерировало отдельные запросы поля OR для каждого токена? - person Tom Zahner; 10.09.2013
comment
QueryParser должен сделать это за вас. Вы читали документацию по синтаксису запросов, на которую я ссылался? Есть ли здесь какая-то конкретная проблема? - person femtoRgon; 10.09.2013
comment
Я думаю, моя проблема в том, что Examine fluent API Examine.LuceneEngine.SearchCriteria.LuceneSearchCriteria.Field(string fieldName, string fieldValue) генерирует фразовый запрос вместо двух терминов ИЛИ. Он использует StandardAnalyzer для токенизации входного текста (это то, что я хочу, чтобы он делал), но он не генерирует точный тип запроса, который мне нужен. Я не вижу способа изменить это поведение без повторной реализации свободного API, поэтому я думаю, что мне просто придется вручную сгенерировать необработанный запрос completeNodeText:(firstterm OR secondterm) - person Tom Zahner; 10.09.2013
comment
(продолжение) Что означает либо конкатенацию строк / ручную разметку входной строки, либо использование другого строго типизированного API запросов (кроме Examine fluent API)? - person Tom Zahner; 10.09.2013
comment
Ах я вижу. Да, я считаю, что вам нужно использовать RawQuery. Запрос поля не запускается через QueryParser, поэтому он не будет генерировать несколько терминов из вашей строки (т. Е. Синтаксис запроса Lucene не используется для этого). Одно замечание, если это упрощает ситуацию, completeNodeText:(firstterm secondterm) вполне достаточно, поскольку OR фактически является оператором по умолчанию. - person femtoRgon; 11.09.2013