lucene 初探 - 查詢

来源:https://www.cnblogs.com/elvinle/archive/2017/12/27/8110258.html
-Advertisement-
Play Games

lucene初探, 是為了後面solr做準備的. 如果跳過lucene, 直接去看solr, 估計有點懵. 由於時間的關係, lucene查詢方法也有多個, 所以單獨出來. 一. 精確查詢 在查詢的時候, 新建一個Term對象, 進去精確匹配. 前一篇提到過, 經過分詞器分下來的每一個詞或者一段話, ...


lucene初探, 是為了後面solr做準備的. 如果跳過lucene, 直接去看solr, 估計有點懵. 

由於時間的關係, lucene查詢方法也有多個, 所以單獨出來.

 一. 精確查詢

     /**
     * 獲取 查找對象
     * @return
     * @throws Exception
     */
    private IndexSearcher getSearcher() throws Exception {
        //1. 創建一個directory對象, 也就是索引庫存放的位置
        Directory directory = FSDirectory.open(new File(indexDir));

        //2. 創建一個indexReader對象, 需要指定directory
        IndexReader indexReader = DirectoryReader.open(directory);

        //3. 創建一個indexSearcher對象, 需要指定indexReader對象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        return indexSearcher;
    }

     /**
     * 輸出信息到控制台
     * @param indexSearcher
     * @param query
     * @throws Exception
     */
    public void sout(IndexSearcher indexSearcher, Query query) throws Exception {
        //5. 執行查詢
        TopDocs topDocs = indexSearcher.search(query, 5);

        //6. 返回查詢結果
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
            //獲取文檔id
            int doc = scoreDoc.doc;
            //根據文檔id獲取文檔
            Document document = indexSearcher.doc(doc);
            //文件名字
            String fileName = document.get("fileName");
            //文件大小
            String fileSize = document.get("fileSize");
            //文件路徑
            String filePath = document.get("filePath");
            //文件內容
            String fileContent = document.get("fileContent");

            System.out.println("fileName : " + fileName);
            System.out.println("fileSize : " + fileSize);
            System.out.println("filePath : " + filePath);
            System.out.println("fileContent : " + fileContent);
            System.out.println("-----------------------");
        }
    }

     /**
     * 精確查詢
     *
     * @throws Exception
     */
    @Test
    public void searchIndex() throws Exception {

        //1. 獲取查詢對象
        IndexSearcher indexSearcher = getSearcher();

        //2. 創建一個TermQuery對象, 指定查詢的域和查詢的關鍵詞
        Query query = new TermQuery(new Term("fileName", "生活"));

        sout(indexSearcher, query);

        //3. 關閉IndexReader 對象
        indexSearcher.getIndexReader().close();
    }

在查詢的時候, 新建一個Term對象, 進去精確匹配. 前一篇提到過, 經過分詞器分下來的每一個詞或者一段話, 就是一個Term.

這裡在新建Term的時候, 傳入的是 功能變數名稱 和 要搜索的詞.

這裡, 一個Term對象, 只有一個域, 那如果我想查詢多個域怎麼辦呢.

 

二. 組合查詢

/**
 * 組合查詢
 */
@Test
public void queryBoolean() throws Exception {
    IndexSearcher searcher = getSearcher();

    BooleanQuery query = new BooleanQuery();

    Query query1 = new TermQuery(new Term("fileName", "生活"));
    Query query2 = new TermQuery(new Term("fileContent", "生活"));

    query.add(query1, BooleanClause.Occur.MUST);
    query.add(query2, BooleanClause.Occur.SHOULD);

    //System.out.println(query);

    sout(searcher, query);

    searcher.getIndexReader().close();
}

這裡的Occur枚舉值, 有三個, must, should, must_not .

must : 相當於sql裡面的 and 連接

should : 相當於 or , 可有可沒有

must_not : 相當於 != , 不包含

這裡如果列印query, 會顯示:  +fileName:生活  fileContent:生活

這是lucene的一種語法, lucene可以根據語法來查詢數據. 後面會提到. 如果是must_not , 則使用減號. 

如: 將上面的query2使用 MUST_NOT 連接, 則顯示成: +fileName:生活  -fileContent:生活

 

三 . 查詢所有

一般查詢資料庫的時候, 都會提供一個 getAll 方法, 用於查詢滿足條件的所有數據, 當不傳條件時, 就查詢所有

lucene也提供了一個查詢所有的方法 : MatchAllDocsQuery 

/**
 * 查詢所有
 *
 * @throws Exception
 */
@Test
public void queryAll() throws Exception {
    IndexSearcher searcher = getSearcher();

    Query query = new MatchAllDocsQuery();

    sout(searcher, query);

    searcher.getIndexReader().close();
}

 

四. 數值區間查詢

/**
 * 數值區間查詢
 *
 * @throws Exception
 */
@Test
public void queryNumericRange() throws Exception {
    IndexSearcher searcher = getSearcher();

    Query query = NumericRangeQuery.newLongRange("fileSize", 10L, 647L, true, true);

    sout(searcher, query);

    searcher.getIndexReader().close();
}

這裡的語法輸出就是 :  fileSize:[40 to 647]

這是因為我後面兩個都設置為true, 表示包含關係. 如果都設置為false, 就是 {40 to 647}

 

五. 分詞器解析查詢

如前面提到的, 我輸入一句話查詢, 結果展示的結果卻並不是按照我輸入的全匹配結果. 

那是因為在查詢之前, 對輸入的信息, 進行了分詞器解析, 然後根據解析結果, 再去查詢數據.

/**
 * 條件解析對象查詢
 *
 * @throws Exception
 */
@Test
public void queryParser() throws Exception {

    IndexSearcher searcher = getSearcher();

    QueryParser queryParser = new QueryParser("fileName", new IKAnalyzer());

    //Query query = queryParser.parse("*:*");
    Query query = queryParser.parse("fileName:這花好漂亮");
    //Query query = queryParser.parse("花");

    sout(searcher, query);

    searcher.getIndexReader().close();
}

*:* 表示查詢所有. 不管是哪個域.

fileName:這花好漂亮 : 表示在fileName域中, 將 "這花好漂亮" 分詞解析後, 進行查詢

花 : 在fileName域中, 查詢花. 因為在QueryParse創建的時候, 指定了域為 fileName

即使我在QueryParser裡面指定了要查詢的域, 但是在parse的時候, 我可以重新指定域.

這裡需要註意的是, 在上面數值區間查詢的時候, 如果我直接寫語法進去查詢, 是查不出來的. 因為數值類型變了. 通過語法輸進去, 變成字元串類型了. 

從結果中可以看到, 我輸入 這花好漂亮, 查出來的卻是 軍中綠花. 這就是分詞的作用了.

 

六. 多域分詞查詢

/**
 * 條件解析對象查詢
 *
 * @throws Exception
 */
@Test
public void queryMultiParser() throws Exception {

    IndexSearcher searcher = getSearcher();

    String[] fields = {"fileName", "fileContent"};
    MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, new IKAnalyzer());

    Query query = queryParser.parse("生活大爆炸");

    sout(searcher, query);

    searcher.getIndexReader().close();
}

多域分詞查詢, 沒啥好說的了. 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文簡單的介紹了Servlet處理響應的基本流程以及Servlet的生命周期 ...
  • 一、wxPython介紹 1、wxPython是Python語言的一套優秀的GUI圖形庫。wxPython可以很方便的創建完整的、功能鍵全的GUI用戶界面。 wxPython是作為優秀的跨平臺GUI庫wxWidgets的Python封裝和Python模塊的方式提供給用戶的。 2、wxPython是跨 ...
  • 原題是這樣的: 給出一個字元串數組S,找到其中所有的亂序字元串(Anagram)。如果一個字元串是亂序字元串,那麼他存在一個字母集合相同,但順序不同的字元串也在S中。 樣例 對於字元串數組 ["lint","intl","inlt","code"] 返回 ["lint","inlt","intl"] ...
  • Pandas基礎篇 Pandas基於Numpy開發,提供了很多高級的數據處理功能。 1、Pandas中的數據對象 Series和DataFrame是Pandas中最常用的兩個對象。 1.1 Series對象 是Pandas中最基本的對象,可用Numpy的數組處理函數直接對Series對象進行處理。支 ...
  • 許可權修飾符 許可權修飾符包括public、private、protected和不加任何修飾符的default,它們都可以修飾方法和變數。其中public和預設的default(不加任何修飾符)這兩個還可以修飾class。private和protected修飾類的情況只能在使用內部類時修飾,正常情況下不 ...
  • 類路徑(classpath) java編譯器編譯.java文件和java虛擬機執行.class文件時的路徑和寫法不一樣。 在沒有設置任何classpath環境變數的情況下,javac可以編譯全路徑的.java文件。例如: 編譯後,在.java同路徑目錄下生成class文件。 預設java虛擬機要從c ...
  • 基礎 類有屬性和方法,它們對本類有效(作用範圍)。類的屬性就是成員變數,它預設會賦值初始化。類的方法是類具有的一些行為。 類是抽象的,將它們實例化後就是對象(通過new進行實例化),各實例化後的對象都具有這些成員變數的屬性,且賦有具體的值,如果某對象沒有為成員變數賦值,則採用預設初始化時的值。每個n ...
  • 前面 lucene 初探 都是為了solr打基礎的. 雖然lucene 的filter 沒有涉及, 但是打基礎, 差不多夠用了. 一. solr 和 lucene 的區別 這裡我就用自己的理解來說了, 可能不全, 但是應該夠用了, 網上能搜到官方一點的. 首先, solr 是基於 lucene的. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...