如何使用QueryParser执行包含特殊字符的lucene查询?

2022-09-01 21:13:58

事情是这样的。我在索引中存储了一个术语,其中包含特殊字符,例如“-”,最简单的代码是这样的:

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做了一些事情来省略查询字符串中的特殊字符。我尝试调试,我发现字符串被拆分,实际查询是这样的:“message:1111 message:2222 message:3333”。我不知道卢塞恩到底做了什么...

那么,如果我想使用特殊字符执行查询,我该怎么办?我应该重写分析器还是从默认分析器继承查询分析器?以及如何?...

更新:

1 @The New Idiot @femtoRgon,我已经尝试了QueryParser.escape(queryStr),如问题中所述,但它仍然不起作用。

2 我尝试了另一种方法来解决这个问题。我从 Tokenizer 派生了一个 QueryTokenizer,并且只按空格剪切单词,将其打包到一个 QueryAnalyzer 中,该分析器派生自 Analyzer,最后将 QueryAnalyzer 传递到 QueryParser 中。

现在它的工作原理。最初它不起作用,因为默认的标准分析器根据默认规则(将某些特殊字符识别为拆分器)剪切了queryStr,当查询传递到QueryParser中时,标准分析器已经删除了特殊字符。现在我使用自己的方式来剪切queryStr,它只将空间识别为拆分器,因此特殊字符保留在查询中等待处理,这有效。

3 @The新白痴@femtoRgon,谢谢你回答我的问题。


答案 1

我不确定这一点,但我想你需要逃脱.根据Lucene文档-\

“-”或“禁止”运算符排除在“-”符号后包含该术语的文档。

Lucene 支持转义作为查询语法一部分的特殊字符。当前列表的特殊字符是

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

要对这些字符进行转义,请在字符前使用 \。

还要记住,如果某些字符在Java中具有特殊含义,则需要转义两次。


答案 2

您可以将值添加为 addValue() 而不是 add 或 addText。然后使用KyewordAnalyzer而不是Standard Analyzer搜索特殊字符。或使用 addValue() 添加数据,并在 luke 中搜索数据时,将特殊字符替换为通配符搜索字符 (?)。我尝试了两种方式和工作


推荐