9、索引庫的查詢三之:Lucene的多樣化查詢

1.4   Lucene的多樣化查詢
  • 在指定的項範圍內搜索-TermRangeQuery類
  • 通過字符串搜索-PrefixQuery類
  • 組合查詢-BooleanQuery類
  • 通過短語搜索-PhraseQuery類
  • 通配符查詢-WildcardQuery類
  • 搜索類似項-FuzzyQuery類
  • 不匹配文檔-MatchNoDocsQuery類
  • 解析查詢表達式-QueryParser類
  • 多短語查詢-MultiPhraseQuery類
好,我們分別對上面的類進行分析和例子的說明
TermRangeQuery類的說明
//TermRangeQuery 的查詢方式 集合查詢的方式
@Test
public void testTermRangeQuery() throws Exception {
    //以讀的方式打開索引庫
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //創建一個IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //創建一個IndexSearcher對象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    //創建一個查詢對象
    //參數:1、要搜索的域 2、區間 以BytesRef中的值爲開頭,3、以BytesRef中的值爲結尾, 4、是否包含  'a'  5、是否包含 'f'
    Query query = new TermRangeQuery("names",new BytesRef("a"),new BytesRef("f"),true,false);
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document對象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("names"));
    }
    indexSearcher.getIndexReader().close();
}
PrefixQuery類的說明
//PrefixQuery 的查詢方式 可表示爲 匹配包含具有指定前綴的術語的文檔的查詢
@Test
public void testPrefixQuery () throws Exception {
    //以讀的方式打開索引庫
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //創建一個IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //創建一個IndexSearcher對象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    //創建一個查詢對象
    //參數Term
    Query query = new PrefixQuery(new Term("name","web"));
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document對象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("name"));
    }
    indexSearcher.getIndexReader().close();
}
BooleanQuery類的說明
//組合條件查詢
@Test
public void testBooleanQuery() throws Exception {
    //以讀的方式打開索引庫
     Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //創建一個IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //創建一個IndexSearcher對象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    //創建查詢條件
    Query query1 = new TermQuery(new Term("name", "apache"));
    Query query2 = new TermQuery(new Term("content", "lucene"));
    //創建一個查詢對象 並添加值
    BooleanQuery query = new BooleanQuery.Builder().add(query1, BooleanClause.Occur.MUST).add(query2, BooleanClause.Occur.MUST_NOT).build();
   //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document對象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("name"));
    }
    indexSearcher.getIndexReader().close();
}
MUST 相當於 and
SHOULD 相當於 or
MUST_NOT 相當於 not 非
FILTER 除MUST的值
PhraseQuery類的說明
//短語之間的查詢
@Test
public void testPhraseQuery() throws Exception {
    //以讀的方式打開索引庫
     Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //創建一個IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //創建一個IndexSearcher對象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章內容:  軟件開發程序員博客文章收藏網提供'lucene多條件查詢'相關的博客文章收藏
     * 如果setSlop設置 小於2的值 則沒有結果 ,因爲 開發 程序員是兩個不短句,只有大於等於2時,才成立 
     */
    //創建一個查詢對象 並添加值
    PhraseQuery.Builder builder=new PhraseQuery.Builder().setSlop(3).add(new Term("text","軟件開發")).add(new Term("text","文章"));
    PhraseQuery query=builder.build();
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document對象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}// 看api上還有一些其他的說明,待研究
WildcardQuery類的說明
//模糊匹配查詢
@Test
public void testWildcardQuery() throws Exception {
    //以讀的方式打開索引庫
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //創建一個IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //創建一個IndexSearcher對象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章內容:  軟件開發程序員博客文章收藏網提供'lucene多條件查詢'相關的博客文章收藏
     *   ?代表1個字符  *代表0個或N個字符
     */
    //創建一個查詢對象 並添加值
    Query query=new WildcardQuery(new Term("text","軟件*開發"));
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document對象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}
FuzzyQuery類的說明
//模糊匹配查詢 找相似的索引值
@Test
public void testFuzzyQuery() throws Exception {
    //以讀的方式打開索引庫
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //創建一個IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //創建一個IndexSearcher對象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章內容:  軟件開發程序員博客文章收藏網提供'lucene多條件查詢'相關的博客文章收藏
     * 注意FuzzyQuery是區分大小寫的,同時默認的編輯距離的值是2
     * 注意兩個Term之間的編輯距離必須小於兩者中最小者的長度
     * 還可以設置第三個參數,第三個參數爲前綴的長度 默認是0 
     */
    //創建一個查詢對象 並添加值
    Query query=new FuzzyQuery(new Term("text","conerib"),1);
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document對象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}
QueryParser類的說明 引用org.apache.lucene.queryparser.classic
//QueryParser匹配查詢
@Test
public void testQueryParser() throws Exception {
    //以讀的方式打開索引庫
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //創建一個IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //創建一個IndexSearcher對象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章內容:  軟件開發程序員博客文章收藏網提供'lucene多條件查詢'相關的博客文章收藏
     */
    //創建查詢
    //第一個參數是默認搜索域,如果查詢時不指定要查詢的域,
    //會到默認搜索域上進行搜索,如果指定了就按照指定的域進行搜索。
    //第二個參數:分析器對象
    QueryParser queryParser=new QueryParser("context",new MyWordAnalyzer());
    Query query=queryParser.parse("text:軟件開發");
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document對象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}
這裏做一個補充:
1、基礎的查詢語法:
域名:關鍵詞
Name:java
2、匹配所有文檔:
*:*
3、範圍查詢語法:
:[最小值 TO最大值]
age:[0 TO 1000]
注意:TO要大寫 
lucene中範圍查詢不支持數值類型,如果要查詢數值類型的範圍還需要使用IntPoint等方式
僅適用於字符串類型。此語法在solr中支持數值類型。
4、組合條件查詢
+name:apache -name:lucene
+:代表必須滿足此條件,相當於     Occur.MUST
-:必須不滿足此條件Occur.MUST_NOT
name:apache name:lucene
什麼都沒有:應該滿足此條件。Occur.SHOULD
Occur.MUST 查詢條件必須滿足,相當於and+(加號)
Occur.SHOULD 查詢條件可選,相當於or空(不用符號)
Occur.MUST_NOT 查詢條件不能滿足,相當於not非-(減號)
 
查詢語法的第二種寫法:
+name:apache +name:lucenename:apache AND name:lucene
name:apache name:lucenename:apache OR name:lucene
name:apache -name:lucenename:apache NOT name:lucene
MultiFieldQueryParser 類
//MultiFieldQueryParser 類
@Test
public void  testMultiFieldQueryParser() throws Exception {
    //以讀的方式打開索引庫
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //創建一個IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //創建一個IndexSearcher對象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章內容:  軟件開發程序員博客文章收藏網提供'lucene多條件查詢'相關的博客文章收藏
     */
    //創建查詢
    //第一個參數是默認搜索域,如果查詢時不指定要查詢的域,
    //會到默認搜索域上進行搜索,如果指定了就按照指定的域進行搜索。
    //第二個參數:分析器對象
    //默認搜索域  配置多個域
    String[] fields = {"text", "content"};
    MultiFieldQueryParser queryParser=new MultiFieldQueryParser(fields,new MyWordAnalyzer());
    Query query=queryParser.parse("軟件開發");
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document對象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}
多短語查詢-MultiPhraseQuery類
//MultiFieldQueryParser 類
@Test
public void  testMultiPhraseQuery() throws Exception {
    //以讀的方式打開索引庫
    Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
    //創建一個IndexReader
    IndexReader indexReader = DirectoryReader.open(directory);
    //創建一個IndexSearcher對象
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * 原文章內容:  軟件開發程序員博客文章收藏網提供'lucene多條件查詢'相關的博客文章收藏
     */
    Term[] terms = new Term[]{new Term("text", "lucene"),new Term("text", "收藏網")};
    Term term=new Term("text", "查詢");
    //多個add之間認爲是OR操作,即(lucene 和收藏網 )與查詢之間的slop值,滿足多個 Term[] 的參數
    MultiPhraseQuery query = new MultiPhraseQuery.Builder().add(terms).add(term).setSlop(2).build();
    //執行查詢
    TopDocs topDocs = indexSearcher.search(query, 10);
    System.out.println("查詢結果總數量:" + topDocs.totalHits);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        //取document對象
        Document document = indexSearcher.doc(scoreDoc.doc);
        System.out.println(document.get("text"));
    }
    indexSearcher.getIndexReader().close();
}

下面是小編的微信轉帳二維碼,小編再次謝謝讀者的支持,小編會更努力的

----請看下方↓↓↓↓↓↓↓

百度搜索 Drools從入門到精通:可下載開源全套Drools教程

深度Drools教程不段更新中:


更多Drools實戰陸續發佈中………

掃描下方二維碼關注公衆號 ↓↓↓↓↓↓↓↓↓↓



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章