2013-07-24 28 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中搜索數據時,將特殊字符替換爲通配符搜索字符(?)。我已經嘗試了兩種方法和工作