Lucene подстановочные запросы - PullRequest
3 голосов
/ 12 марта 2010

У меня есть вопрос, касающийся Lucene.

У меня есть форма, и я получаю от нее текст, и я хочу выполнить полнотекстовый поиск по нескольким полям. Предположим, я получил от ввода текст «textToLook».

У меня есть Lucene Analyzer с несколькими фильтрами. Один из них - lowerCaseFilter, поэтому при создании индекса слова будут в нижнем регистре.

Представьте, что я хочу выполнить поиск в двух полях field1 и field2, чтобы запрос lucene был примерно таким (обратите внимание, что textToLook теперь равно texttolook):

field1: texttolook* field2:texttolook*

В моем классе у меня есть что-то подобное для создания запроса. Я работаю, когда нет подстановочного знака.

String text = "textToLook";
String[] fields = {"field1", "field2"};
//analyser is the same as the one used for indexing
Analyzer analyzer = fullTextEntityManager.getSearchFactory().getAnalyzer("customAnalyzer");
MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, analyzer);
org.apache.lucene.search.Query queryTextoLibre = parser.parse(text);

С этим кодом запрос будет:

field1: texttolook field2:texttolook

но если я установлю текст на "textToLook *", я получу

field1: textToLook* field2:textToLook*

, который не будет правильно найден, так как индексы в нижнем регистре.

Я прочитал на сайте Lucene это:

"Подстановочные, префиксные и нечеткие запросы не передаются через анализатор, который является компонентом, который выполняет такие операции, как lowercasing "

Моя проблема не может быть решена путем установки нечувствительного к регистру поведения, потому что у моего анализатора есть другие поля, которые, например, удаляют некоторые суффиксы слов.

Я думаю, что смогу решить проблему, получив, как будет выглядеть текст после прохождения фильтров моего анализатора, затем я смогу добавить «*», а затем я мог бы построить Запрос с MultiFieldQueryParser. Таким образом, в этом примере я получаю «textToLower», и после перехода к этим фильтрам я могу получить «texttolower». После этого я мог сделать "текстотелу *".

Но есть ли способ получить значение моей текстовой переменной после прохождения всех фильтров моего анализатора? Как я могу получить все фильтры моего анализатора? Это возможно?

Спасибо

1 Ответ

1 голос
/ 12 марта 2010

Вы можете использовать QueryParser.setLowercaseExpandedTerms (true)?

http://wiki.apache.org/lucene-java/LuceneFAQ#Are_Wildcard.2C_Prefix.2C_and_Fuzzy_queries_case_sensitive.3F

** РЕДАКТИРОВАТЬ **

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

Вы можете создать подкласс QueryParser и переопределить

protected Query getWildcardQuery(String field, String termStr) throws ParseException

для запуска termStr через анализатор до создания WildcardQuery.

Впрочем, это может не соответствовать ожиданиям пользователя. Есть причина, почему они решили не запускать термины с подстановочными символами через анализатор, согласно часто задаваемым вопросам:

причина пропуска анализатора это то, что если вы искали «собаки» вы бы не хотели «собак» сначала связано с "собакой", так как будет соответствовать «собака *», которая не предполагаемый запрос.

...