BooleanQuery也是實際開發過程中經常使用的一種Query。它其實是一個組合的Query,在使用時可以把各種Query對象添加進去並標明它們之間的邏輯關系。
BooleanQuery本身來講是一個布爾子句的容器,它提供了專門的API方法往其中添加子句,並標明它們之間的關系,以下代碼為BooleanQuery提供的用於添加子句的API接口:
public void add(Query query, boolean required, boolean prohibited);
注意:BooleanQuery是可以嵌套的,一個BooleanQuery可以成為另一個BooleanQuery的條件子句。
package ch11; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; public class BooleanQueryTest1 { public static void main(String[] args) throws Exception { // 生成新的Document對象 Document doc1 = new Document(); doc1.add(Field.Text("name", "word1 word2 word3")); doc1.add(Field.Keyword("title", "doc1")); Document doc2 = new Document(); doc2.add(Field.Text("name", "word1 word4 word5")); doc2.add(Field.Keyword("title", "doc2")); Document doc3 = new Document(); doc3.add(Field.Text("name", "word1 word2 word6")); doc3.add(Field.Keyword("title", "doc3")); // 生成索引書寫器 IndexWriter writer = new IndexWriter("c://index", new StandardAnalyzer(), true); // 添加到索引中 writer.addDocument(doc1); writer.addDocument(doc2); writer.addDocument(doc3); writer.close(); Query query1 = null; Query query2 = null; BooleanQuery query = null; Hits hits = null; // 生成IndexSearcher對象 IndexSearcher searcher = new IndexSearcher("c://index"); query1 = new TermQuery(new Term("name", "word1")); query2 = new TermQuery(new Term("name", "word2")); // 構造一個布爾查詢 query = new BooleanQuery(); // 添加兩個子查詢 query.add(query1, true, false); query.add(query2, true, false); hits = searcher.search(query); printResult(hits, "word1和word2"); } public static void printResult(Hits hits, String key) throws Exception { System.out.println("查找 /"" + key + "/" :"); if (hits != null) { if (hits.length() == 0) { System.out.println("沒有找到任何結果"); } else { System.out.println("找到" + hits.length() + "個結果"); for (int i = 0; i < hits.length(); i++) { Document d = hits.doc(i); String dname = d.get("title"); System.out.print(dname + " "); } System.out.println(); System.out.println(); } } } }
代碼首先構造了兩個TermQuery,然后構造了一個BooleanQuery的對象,並將兩個TermQuery當成它的查詢子句加入Boolean查詢中。
再來看一下BooleanQuery的add方法,除了它的第一個參數外,它還有另外兩個布爾型的參數。第1個參數的意思是當前所加入的查詢子句是否必須滿足,第2個參數的意思是當前所加入的查詢子句是否不需要滿足。這樣,當這兩個參數分別選擇true和false時,會有4種不同的組合。
true &false:表明當前加入的子句是必須要滿足的。 false&true:表明當前加入的子句是不可以被滿足的。 false&false:表明當前加入的子句是可選的。 true&true:錯誤的情況。
由前面的示例可以看出由於加入的兩個子句都選用了true&false的組合,因此它們兩個都是需要被滿足的,也就構成了實際上的“與”關系
如果是要進行“或”運算,則可按如下代碼來構建查詢子句
query.add(query1, false, false); query.add(query2, false, false);
由於布爾型的查詢是可以嵌套的,因此可以表示多種條件下的組合。不過,如果子句的數目太多,可能會導致查找效率的降低。因此,Lucene給出了一個默認的限制,就是布爾型Query的子句數目不能超過1024。