Lucene的查詢、Occur.SHOULD Occur.MUST Occur.MUST_NOT的組合使用

  • 1.MUST和MUST:取得連個查詢子句的交集。
    • 2.MUST和MUST_NOT:表示查詢結果中不能包含MUST_NOT所對應得查詢子句的檢索結果。
    • 3.SHOULD與MUST_NOT:連用時,功能同MUST和MUST_NOT。
    • 4.SHOULD與MUST連用時,結果爲MUST子句的檢索結果,但是SHOULD可影響排序。
    • 5.SHOULD與SHOULD:表示“或”關係,最終檢索結果爲所有檢索子句的並集。
    • 6.MUST_NOT和MUST_NOT:無意義,檢索無結果。

查看本文章 前,可參考前一篇文章,因爲它是在上一篇的基礎進行測試的,基本測試代碼如下:

package com.ckinghan.lucene;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiDocsAndPositionsEnum.EnumWithSlice;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;

public class QuerIndex {

    /**
     * 查詢lucene索引數據 @創建時間:2017年10月7日22:57:00
     */
    public void query(Query query) {
        try {
            // 指定查詢的索引目錄
            Directory directory = FSDirectory.open(new File("D:" + File.separator + "lucene_index" + File.separator));
            // 創建流對象
            IndexReader reader = DirectoryReader.open(directory);
            // 通過流對象創建索引搜索對象
            IndexSearcher searcher = new IndexSearcher(reader);
            // 將查詢到的指定索引域數據賦值給TopDocs
            TopDocs topDocs = searcher.search(query, 10);
            // 根據獲取查詢到的總數據
            int totalHits = topDocs.totalHits;
            // 輸出
            System.out.println("共查詢到數據總數爲:" + totalHits);
            System.out.println();
            // 將查詢到的索引數據賦值給數組
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;
            // 如果未查詢到數據,則輸出提示
            if (scoreDocs == null || scoreDocs.length == 0) {
                System.out.println("未查詢到數據");
            } else {
                // 如果查詢到的有數據。則循環輸出
                for (ScoreDoc doc : scoreDocs) {
                    // 獲取索引ID
                    int docID = doc.doc;
                    // 根據索引數據查詢文檔中對應的數據
                    Document document = searcher.doc(docID);

                    // 將查詢到的數據輸出
                    System.out.println("ID:" + document.get("id"));
                    System.out.println("name:" + document.get("name"));
                    System.out.println("price:" + document.get("price"));
                    System.out.println("pic:" + document.get("pic"));
                    System.out.println("description:" + document.get("description"));
                    System.out.println("==================================");
                    System.out.println();
                    System.out.println();
                }

            }
            // 關閉流
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

創建第一種查詢方法–》QueryParse查詢,這個查詢方法用的比較多。

    /**
     * QueryParse查詢 @創建時間:2017年10月7日23:00:15
     */
    @Test
    public void queryParser() throws ParseException {
        // 創建分詞對象
        Analyzer analyzer = new StandardAnalyzer();
        // 通過指定的分詞對象、查詢域名稱創建QueryParser
        QueryParser parser = new QueryParser("id", analyzer);
        // 指定查詢條件創建query
        Query query = parser.parse("id:7");

        // 查詢
        query(query);
    }

因爲ID爲7的數據是在測試更新的方法創建的,並未將所有數據補充完整,所有會有一部分數據爲空。執行結果如下:

共查詢到數據總數爲:1

ID:7
name:null
price:null
pic:null
description:null
==================================


創建第二種查詢方法–》TermQuery查詢,代碼如下:

    @Test
    public void termQuery() {
        //Term是lucene最小的查詢單位了,一般會指定查詢的域名及查詢的值
        Query query = new TermQuery(new Term("name", "java"));

        // 調用方法查詢
        query(query);
    }

查詢結果如下:

共查詢到數據總數爲:1

ID:3
name:java spring mybatis Struts2 springMVC hibernate
price:99.25
pic:6546545656.jpg
description:null
==================================

創建第三種查詢方法–》NumericRangeQuery查詢 ,它有很多重載的方法,根據須要選擇,代碼如下,

    /**
     * NumericRangeQuery查詢 @創建時間:2017年10月7日23:09:55
     */
    @Test
    public void numbericRangeQuery() {
        // NumbericRangeQuery 參數:查詢域名稱,最小值,最大值 ,是否包含最小值,是否包含最大值
        Query query = NumericRangeQuery.newFloatRange("price", 10f, 60f, true, true);

        // 查詢
        query(query);
    }

查詢price的值10f/60f之間的結果如下:

共查詢到數據總數爲:2

ID:4
name:天氣你好啊哦咯看i我看
price:22.22
pic:365456564.jpg
description:null
==================================


ID:5
name:愛奇藝
price:54.25
pic:adsfasdfa.jpg
description:null
==================================


創建第四種查詢方法–》BooleanQuery查詢,這個玩意就比較複雜了,代碼如下:

/**
     * BooleanQuery查詢
     * @創建時間:2017年10月7日23:19:07
     * Occur參數說明:
     *  Occur.MUST              : 必須滿足查詢條件
     *  Occur.MUST_NOT          : 不滿足條件的數據
     *  Occur.SHOULD            : 邏輯OR
     * 
     * 組合功能如下:
     * 1.MUST和MUST:取得連個查詢子句的交集。 
     * 2.MUST和MUST_NOT:表示查詢結果中不能包含MUST_NOT所對應得查詢子句的檢索結果。 
     * 3.SHOULD與MUST_NOT:連用時,功能同MUST和MUST_NOT。
     * 4.SHOULD與MUST連用時,結果爲MUST子句的檢索結果,但是SHOULD可影響排序。
     * 5.SHOULD與SHOULD:表示“或”關係,最終檢索結果爲所有檢索子句的並集。
     * 6.MUST_NOT和MUST_NOT:無意義,檢索無結果。
     */
    @Test
    public void booleanQuery() {
        BooleanQuery query = new BooleanQuery();
        Query termQuery = new TermQuery(new Term("name", "java"));
        Query numericRangeQuery = NumericRangeQuery.newFloatRange("price", 10f, 60f, true, true);
        query.add(termQuery, Occur.SHOULD);
        query.add(numericRangeQuery, Occur.SHOULD);
        // 查詢
        query(query);
    }

查詢的結果如下:

共查詢到數據總數爲:3

ID:3
name:java spring mybatis Struts2 springMVC hibernate
price:99.25
pic:6546545656.jpg
description:null
==================================


ID:4
name:天氣你好啊哦咯看i我看
price:22.22
pic:365456564.jpg
description:null
==================================


ID:5
name:愛奇藝
price:54.25
pic:adsfasdfa.jpg
description:null
==================================


創建第五種查詢方式–》multiFieldQueryParser(),這個功能很強大,具體代碼如下:

/**
     * 條件組合查詢:
     * Occur.MUST           必須滿足            相當於and          可以用+代表
     * Occur.MUST_NOT   不滿足             相當於not          可以用-代表
     * Occur.SHOULD     或操作             相當於or               可以用空代表
     * 例如:
     * +name:java +description:spring 代碼必須同時滿足這兩個條件,相當於and的
     * +name:java description:spring    必須滿足name=java,後面的條件忽略
     * name:java description:spring       滿足任義一個就可以,相當於or
     * +name:java -description:spring   必須滿足name=java and description<>spring
     * 
     * 範圍查詢:
     *  price:[10f TO 100f]  相當於SQL語句中的  price between 10f and 100f
     * 注意:QueryParser不支持對數字範圍的搜索,它支持字符串範圍。數字範圍搜索建議使用NumericRangeQuery。
     * 
     * 
     * @創建時間:
     */
    @Test
    public void multiFieldQueryParser() throws ParseException{
        //指定多個查詢域名稱
        String[] fields = {"name","description"};
        //指定分詞對象
        Analyzer analyzer = new StandardAnalyzer();
        //創建多域名查詢對象
        MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(fields, analyzer);
        //以下三種方法相等,查詢name = java or description = java的對象
        //Query query = multiFieldQueryParser.parse("name:java description:java");
        //Query query = multiFieldQueryParser.parse("name:java OR description:java");
        Query query = multiFieldQueryParser.parse("java");

        //輸出query的查詢語句內容 
        System.out.println(query);

        //查詢
        query(query);
    }

執行結果如下 :

name:java description:java
共查詢到數據總數爲:1

ID:3
name:java spring mybatis Struts2 springMVC hibernate
price:99.25
pic:6546545656.jpg
description:null
==================================


發佈了153 篇原創文章 · 獲贊 69 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章