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

这就是事情。 我有一个术语存储在索引中,其中包含特殊字符,如’ – ‘,最简单的代码如下:

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

所以如果我想用特殊字符执行查询,我该怎么办? 我应该重写分析器还是从默认值中inheritance一个queryparser? 怎么样?…

更新:

1 @The New Idiot @femtoRgon,我已经尝试了问题中所述的QueryParser.escape(queryStr),但它仍然无效。

2我尝试了另一种解决问题的方法。 我从Tokenizer派生了一个QueryTokenizer,只用空格切换单词,将它打包成QueryAnalyzer,它派生自Analyzer,最后将QueryAnalyzer传递给QueryParser。

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

3 @The New Idiot @femtoRgon,感谢您回答我的问题。

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

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

再次,

Lucene支持转义属于查询语法的特殊字符。 当前列表中的特殊字符是

+ – && || ! (){} [] ^“〜*?:\ /

要逃避这些角色,请在角色前使用\。

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

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