2013-07-24 30 views
17

这是事情。我有存储在索引中,其中包含特殊字符的术语,如“ - ”,最简单的代码是这样的:如何使用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做了省略在查询字符串的特殊字符。我尝试了调试,发现字符串被拆分,实际查询如下所示:“message:1111 message:2222 message:3333”。我不知道究竟是什么Lucene的做...

所以,如果我想用特殊字符执行查询,我该怎么办?我应该重写一个分析器还是继承一个默认的查询分析器?而如何...

更新:在这个问题说,但它仍然无法正常工作

1 @The新白痴@femtoRgon,我已经试过QueryParser.escape(queryStr)。

2我试过另一种方法来解决问题。我从Tokenizer派生了一个QueryTokenizer,并且只通过空格来裁剪这个词,将它打包到派生自Analyzer的QueryAnalyzer中,最后将QueryAnalyzer传递给QueryParser。

现在,它的工作。最初它不起作用,因为默认StandardAnalyzer根据默认规则(将一些特殊字符识别为分隔符)剪切queryStr,当查询传递到QueryParser时,特殊字符已被StandardAnalyzer删除。现在我用我自己的方式来切断queryStr,它只将空间识别为分隔符,所以特殊字符保留在查询中等待处理,并且这可以工作。

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

+1

道歉,我显然没有仔细阅读。但我很困惑:这个'TextField'来自哪里? Lucene的'TextField'不带'Field.Index'参数('Field.Index'已弃用)。要创建一个像这里一样的字段,你应该使用'StringField'。这是某种自定义的'TextField'或什么的? – femtoRgon

+0

对不起,这是我的错。我使用的是Lucene 3.6,Lucene 3.x中没有TextField。正确的代码应该是:'doc.add(new Field(“message”,“1111-2222-3333”,Field.Store.YES,Field.Index.NOT_ANALYZED));'Lucene 4.x和3.x API是非常不同的,我仍然试图理解lucene 4.x API。 –

+0

啊,更有意义。有点偏离主题,但如果你正试图掌握4.x中的变化,你是否看过[迁移指南](http://lucene.apache.org/core/4_0_0/MIGRATE.html)?它呼吁进行重大改变,并提供一些理由。 – femtoRgon

回答

19

我不知道这一点,但我猜你需要逃避-\。根据Lucene docs

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

再次,

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

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

要逃避这些字符,请在字符前使用\。

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

+0

感谢您的回答,我找到了解决这个问题的方法,请参阅我的更新。 –

+1

不要忘记,从Lucene 4.0开始“/”也是一个特殊字符(在正则表达式中使用)。 –

0

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