Как выполнить запрос lucene, содержащий специальный символ, используя QueryParser?

Вот что. У меня есть термин, хранящийся в индексе, который содержит специальный символ, такой как "-", простейший код выглядит так:

Document doc = new Document();
doc.add(new TextField("message", "1111-2222-3333", Field.Store.YES, Field.Index.NOT_ANALYZED));
writer.addDocument(doc);

И затем я создаю запрос с помощью QueryParser, например:

String queryStr = "1111-2222-3333";
QueryParser parser = new QueryParser(Version.LUCENE_36, "message", new StandardAnalyzer(Version.LUCENE_36));
Query q = parser.parse(queryStr);

И затем я использую поисковик для поиска запроса и не получаю никакого результата. Я также пробовал это:

Query q = parser.parse(QueryParser.escape(queryStr));

И все равно никакого результата.

Без использования QueryParser и вместо этого использование TermQuery напрямую может делать то, что я хочу, но этот способ недостаточно гибкий для пользовательских входных текстов.

Я думаю, возможно, StandardAnalyzer сделал что-то, чтобы опустить специальный символ в строке запроса. Я попробовал debug, и я обнаружил, что строка разделена и фактический запрос выглядит так: "message: 1111 message: 2222 message: 3333". Я не знаю, что именно сделал lucene...

Итак, если я хочу выполнить запрос со специальным символом, что мне делать? Должен ли я переписать анализатор или наследовать элемент queryparser из значения по умолчанию? И как?...

Update:

1 @New Idiot @femtoRgon, я пробовал QueryParser.escape(queryStr), как указано в проблеме, но он все еще не работает.

2 Я пробовал другой способ решить проблему. Я получил QueryTokenizer из Tokenizer и вырезал слово только по пространству, упаковал его в QueryAnalyzer, который происходит от Analyzer и, наконец, передал QueryAnalyzer в QueryParser.

Теперь он работает. Первоначально это не работает, потому что по умолчанию StandardAnalyzer разрезал queryStr в соответствии с правилами по умолчанию (которые распознают некоторые специальные символы в качестве разделителей), когда запрос передается в QueryParser, специальные символы уже удаляются стандартным идентификатором. Теперь я использую свой собственный способ разрезать queryStr, и он распознает только пространство как разделитель, поэтому специальные символы остаются в запросе, ожидающем обработки, и это работает.

3 @New Idiot @femtoRgon, спасибо, что ответили на мой вопрос.

Ответы

Ответ 1

Я не уверен в этом, но я думаю, вам нужно избежать - с помощью \. В соответствии с Lucene docs.

Оператор "-" или запрет исключает документы, содержащие термин после символа "-".

Опять же,

Lucene поддерживает экранирование специальных символов, которые являются частью синтаксиса запроса. Специальные символы текущего списка

+ - && ||!() {} [] ^ "~ *?: \/

Чтобы избежать этих символов, используйте символ\перед символом.

Также помните, что некоторые символы вам нужно избежать дважды, если они имеют особое значение в Java.

Ответ 2

вы можете добавить значение как addValue() вместо add или addText. а затем выполнить поиск в специальном символе с помощью KyewordAnalyzer вместо стандартного анализатора. или Добавьте данные с помощью addValue(), и, выполняя поиск данных в luke, замените специальный символ символом поиска(). Я пробовал в обоих направлениях и работает