1. 程式人生 > >使用Lucene.Net實現全文檢索

使用Lucene.Net實現全文檢索

目錄

一 Lucene.NET概述

二 分詞

三 索引

四 搜尋

五 實踐中的問題

一 Lucene.Net概述

  Lucene.Net是一個C#開發的開源全文索引庫,其原始碼包括“核心”與“外圍”兩部分。外圍部分實現輔助功能,而核心部分包括:

  • Lucene.Net.Index 提供索引管理,片語排序。
  • Lucene.Net.Search 提供查詢相關功能。
  • Lucene.Net.Store 支援資料儲存管理,主要包括I/O操作。
  • Lucene.Net.Util 公共類。
  • Lucene.Net.Documents 負責描述索引儲存時的檔案結構管理。
  • Lucene.Net.QueryParsers 提供查詢語法。
  • Lucene.Net.Analysis 負責分析文字。

  全文檢索流程如下:

  一個簡單的全文檢索例項:

  建立索引

  關鍵程式碼形如:

  1. staticvoid createIndex(string title, string content)  
  2.       {  
  3.           LN.Analysis.Analyzer analyzer = new LN.Analysis.Standard.StandardAnalyzer();  
  4.           LN.Index.IndexWriter iw = new
     LN.Index.IndexWriter("Index", analyzer, false);  
  5.           LN.Documents.Document document = new LN.Documents.Document();  
  6.           document.Add(new LN.Documents.Field("title", title, LN.Documents.Field.Store.YES, LN.Documents.Field.Index.TOKENIZED));  
  7.           document.Add(new LN.Documents.Field(
    "content", content, LN.Documents.Field.Store.YES, LN.Documents.Field.Index.TOKENIZED));  
  8.           iw.AddDocument(document); iw.Optimize(); iw.Close();  
  9.       }  

  查詢:

   關鍵程式碼形如:

  1. static List<Item> search(string keyWord)  
  2.        {  
  3.            List<Item> results = new List<Item>();  
  4.            LN.Analysis.Analyzer analyzer = new LN.Analysis.Standard.StandardAnalyzer();  
  5.            LN.Search.IndexSearcher searcher = new LN.Search.IndexSearcher("Index");  
  6.            LN.QueryParsers.MultiFieldQueryParser parser = new LN.QueryParsers.MultiFieldQueryParser(newstring[] { "title""content" }, analyzer);  
  7.            LN.Search.Query query = parser.Parse(keyWord);  
  8.            LN.Search.Hits hits = searcher.Search(query);  
  9.            for (int i = 0; i < hits.Length(); i++)  
  10.            {  
  11.                LN.Documents.Document doc = hits.Doc(i);  
  12.                results.Add(new Item() { Title = doc.Get("title"), Content = doc.Get("content") });  
  13.            } searcher.Close();  
  14.            return results;  
  15.        }  

二 分詞

(一)內建分詞器

  分詞(切詞)是實現全文檢索的基礎,之所以我們能夠讓機器理解我們的自然語言,是因為有了分詞的幫助。分詞工作由Analyzer類完成,它負責把文字切成Token序列,Token就是索引中的單詞。Lucene.Net在兩個地方用到分詞:建立文件索引和分析搜尋關鍵字。其過程示意如下:

  由此可知,在建立索引和搜尋時,必須使用同樣的分詞器,保證其切出相同的Token才能檢索到結果。(Lucene.Net把查詢關鍵字中的單詞叫做“Term”,Term和Token的文字是一樣的,只是某些屬性不一樣。)

  Lucene.Net實現了一些分詞器,其對英文支援較好,但是對中文支援欠佳。

  針對內建分詞器測試結果如下:

  關鍵程式碼形如:

  1. privatestatic List<string> cutWords(string words, Analyzer analyzer)  
  2.      {  
  3.          List<string> results = new List<string>();  
  4.          TokenStream ts = analyzer.ReusableTokenStream(""new StringReader(words));  
  5.          Token token; while ((token = ts.Next()) != null)  
  6.          {  
  7.              results.Add(token.TermText());  
  8.          }  
  9.          ts.Close();  
  10.          return results;  
  11.      }  

  可見,除了StandardAnalyzer外,其它分詞器對中文基本無法處理,需要使用者自行解決。

(二)分詞過程

  分詞實際是由以下型別完成:

  檢視WhitespaceAnalyzer的部分原始碼如下:

  1. publicsealedclass WhitespaceAnalyzer:Analyzer {  
  2.           publicoverride TokenStream TokenStream(System.String fieldName, System.IO.TextReader reader) {   
  3.               returnnew WhitespaceTokenizer(reader);   
  4.           }     
  5.           ...  
  6.       }  

  由此可見,WhitespaceAnalyzer的工作都是交給WhitespaceTokenizer來完成的,並且沒有使用篩選器,這也與之前測試的結果相符。我們可以利用TokenStream的派生型別來實現自定義分詞器。 例如修改上述程式碼來得到一個新的分詞器,功能類似WhitespaceAnalyzer,不同的是將大寫字母變為小寫,其程式碼形如:

  1. publicsealedclass NewWhitespaceAnalyzer:Analyzer {   
  2.     publicoverride TokenStream TokenStream(System.String fieldName, System.IO.TextReader reader) {   
  3.         TokenStream ts = new WhitespaceTokenizer(reader);   
  4.         returnnew LowerCaseFilter(ts);  
  5.     }      
  6.     ...   
  7. }  

(三)中文分詞

  顯然,使用者可以自定義分詞器,來實現中文分詞。但是,大多數使用者不熟悉中文分詞演算法,同時也沒有時間和精力來實現自定義分詞,畢竟分詞並不是我們系統的核心功能。因此,筆者引用了另一箇中文分片語件——盤古分詞。測試結果如下:

  盤古分詞使用步驟如下:

Setp 1:新增相關程式集引用

這裡需要新增2個程式集,PanGu.dll(盤古分詞的核心元件)和PanGu.Lucene.Analyzer.dll(盤古分詞的Lucene元件)。

Step 2:新增中文分詞庫

Step 3:新增並設定配置檔案

Step 4:在Lucene.Net使用盤古分詞

  PanGu.Lucene.Analyzer.dll中定義了Analyzer的派生型別Lucene.Net.Analysis.PanGu.PanGuAnalyzer,與Tokenizer的派生類Lucene.Net.Analysis.PanGu.PanGuTokenizer,語法與Lucene.Net內建分詞器相同。

Step 5:維護分詞庫

  使用DictManage.exe管理和維護詞庫:

三 索引

(一)索引的儲存結構

  為了方便索引大量文件,Lucene.Net中的一個索引包括多個子索引,叫做Segment(段)。每個Segment包括多個可搜尋的文件,叫做Document;每個Document包括多個Field;每個Field又包括多個Term。綜上所述,Lucene.Net的索引檔案的邏輯結構如下:

  索引檔案的物理表示如下:

  Lucene.Net把一個文件寫入索引時,首先生成這個文件的到排索引,然後再把文件的倒排索引合併到段的倒排索引中。

(二)常用型別

  • Directory Lucene.Net的Directory型別實現索引的儲存。常用型別繼承樹如下:

  • IndexWriter 負責將索引寫入Directory。Lucene通過設定快取來提供寫索引的速度,IndexWriter有幾個引數來調整快取的大小,控制Segment的數量,以及寫索引的頻率:
    1. 合併因子(mergeFactor) 這個引數決定一個索引塊中可以存放多少文件(Document)以及把磁碟上的索引段(Segment)合併成一個大索引段的頻率。該引數預設值為10。在預設情況下,快取中Document數達到10時,所有的文件將寫入一個新的Segment。並且,如果Directory的Segment的個數達到10,這10個索引塊會被合併成一個新的Segment。對於大量文件來說,這個值大一些會更好。可以通過“SetMergeFactor(int mergeFactor)”方法來設定、
    2. 最小合併文件數(minMergeDocs)、最大快取文件數(maxBufferedDocs) 預設值為10,它決定快取中Document數量達到多少才能將他們寫入磁碟。該值越大越消耗記憶體,I/O操作越少。(本處,筆者也有些糊塗,筆者感覺兩者類似,不知道具體區別,若理解有誤還請讀者賜教。)
    3. 最大合併文件數(maxMergeDocs) 預設值為Integer.MAX_VALUE,它決定一個索引段(Segment)中的最大文件(Document)數。該值越大越高效,因為預設值以及很大了所以不用改變。
    4. 最大域長度(maxFieldLength) 預設值10000,表示擷取該域中的前10000個Term,前10000個以外的Term將不被索引和檢索。該值可在索引中隨時更改,並即時生效(僅對之後的操作生效,一般該值設定為Integer.MAX_VALUE)。

    IndexWriter的常用方法包括:

    1. Flush/Commit Flush方法與Commit方法相同,都是把快取中的資料提交,可以清除快取。
    2. Close 無論是否發生異常都必須呼叫Close方法,該方法將對檔案進行解鎖,並完成Flush方法的功能。
    3. Optimize Optimize方法用於優化索引,執行相當耗時。
  • Document 包含了可索引文件的資訊。每個Document都有一個編號,但該編號並非永遠不變。
  • Field 類似實體的某個屬性,就像資料庫中的一個列,其成員如下:

  (可以看到,Index的某些欄位我給出的相同的註釋,這是因為向下相容的目的而具有相同的作用。注:高亮顯示將用的TermVector。)

  常用列選項組合及用法如下:

Index Store TermVector 用法
NOT_ANSLYZED YES NO 檔名、主鍵
ANSLYZED YES WITH_POSITUION_OFFSETS 標題、摘要
ANSLYZED NO WITH_POSITUION_OFFSETS 很長的全文
NO YES NO 文件型別
NOT_ANSLYZED NO NO 隱藏的關鍵詞

(三)建立索引

  建立索引流程如下:

相關推薦

使用Lucene.Net實現全文檢索

目錄 一 Lucene.NET概述 二 分詞 三 索引 四 搜尋 五 實踐中的問題 一 Lucene.Net概述   Lucene.Net是一個C#開發的開源全文索引庫,其原始碼包括“核心”與“外圍”兩部分。外圍部分實現輔

Lucene實現全文檢索

1.配置開發壞境 1.1.下載Lucene(http://lucene.apache.org/ ) jdk要求 1.8 以上 1.2.匯入jar包 下載完之後解壓裡面有所需Jar包 2. 編寫入門案列 2.1建立索引 2.2 查詢索引 2.3 中文分析

SSM整合Lucene實現全文檢索

1.Lucene概述Lucene是一款使用Java語言編寫的全文檢索框架Lucene是簡單而功能強大的基於Java的搜尋庫。它可以用於任何應用程式來搜尋功能。 Lucene是開源專案。它是可擴充套件的,高效能的庫用於索引和搜尋幾乎任何型別的文字。 Lucene庫提供了所需的任

SpringCloud學習筆記024---SpringBoot整合Lucene實現全文檢索_分詞_索引_更新_刪除文件_詞條搜尋_多條件查詢

先看程式碼實現,下面有lucene介紹: 測試用例 Github 程式碼 程式碼我已放到 Github ,匯入spring-boot-lucene-demo 專案 新增依賴 <!--對分詞索引查詢解析--> <dependency>

實戰2000W條資料實現全文檢索

一) 前期準備測試: 舊版的MySQL的全文索引只能用在MyISAM表格的char、varchar和text的欄位上。 不過新版的MySQL5.6.24上InnoDB引擎也加入了全文索引,所以具體資訊要隨時關注官網,下載mySql5.7 直接使用,可

springboot+elasticsearch + rabbitMQ實現全文檢索(專案搭建)

最近做一個社群類的專案:實現全文檢索 開發完成做一個總結記錄。 spring-boot-1.5.9.RELEASE ES 5.6.4 首先搭建ES環境 引用大佬文章 搭建ES環境: https://blog.csdn.net/u012270682/article/details/7293

springboot+elasticsearch + rabbitMQ實現全文檢索(項目搭建)

runt mage ans log 127.0.0.1 改變 引用 復制 ping 最近做一個社區類的項目:實現全文檢索 開發完成做一個總結記錄。 spring-boot-1.5.9.RELEASE ES 5.6.4 首先搭建ES環境 引用大佬文章 搭建ES環境: http

springboot+elasticsearch + rabbitMQ實現全文檢索(springboot+ES整合)

known https vnr builder mod hystrix connector uid bsp springboot 2.X 能用 springboot-data-ES 5.X的 用特殊方式引入 5.X的ES 配置 bootstrap.xml 因為在調試,所

Elasticsearch使用REST API實現全文檢索

通過rest api新增檢索資料,閱讀官方文件可以發現,elasticsearch支援動態對映,但是其中有不少問題,且聽慢慢詳解。 本文主要講述三點內容: 1 Elasticsearch常用的rest api 2 Elasticsearch使用bulk命令新增索引資料 ES REST API

java springboot 結合elasticsearch 實現全文檢索 的步驟,有坑請繞行

開啟springboot專案 首先我這裡選擇的是jestClient操作elasticsearch 這裡還有一種方式是通過 ElasticsearchRepostiry類似jpa的一種工具介面,但會隨著ela的版本的修改而變化程式碼,所以首選jestClient

elasticsearch的實現全文檢索

elasticsearch一個準實時的搜尋引擎,基於lucene構建,它的主要強項還是在全文檢索方面。工作中還是使用到了這部分功能,這裡做一個簡單的總結,可以使初次使用的人很快的配置和使用。 一、全文檢索的概念 首先介紹全文檢索的概念,就是對一篇文章進行索

Lucene實踐:全文檢索的基本原理 (轉載)

一、總論 "Apache Lucene(TM) is a high-performance, full-featured text search engine library written entirely in Java. It is a technology suitable for nearly

Lucene實踐:全文檢索的基本原理

一、總論 "Apache Lucene(TM) is a high-performance, full-featured text search engine library written entirely in Java. It is a technology suitable for nearly

【搜尋引擎】Solr Suggester 實現全文檢索功能-分詞和和自動提示

功能需求 全文檢索搜尋引擎都會有這樣一個功能:輸入一個字元便自動提示出可選的短語: 要實現這種功能,可以利用solr的SuggestComponent,SuggestComponent這種方法利用Lucene的Suggester實現,並支援Lucene中可用的所有查詢實現。 實現 1. 配置 manage

Mysql 如何實現全文檢索,關鍵詞跑分

--- ## 一、前言 今天一個同事問我,如何使用 Mysql 實現類似於 ElasticSearch 的全文檢索功能,並且對檢索關鍵詞跑分?我當時腦子裡立馬產生了疑問?為啥不直接用es呢?簡單好用還賊快。但是聽他說,資料量不多,客戶給的時間非常有限,根本沒時間去搭建es,所以還是看一下 Mysql 的全文

Lucene全文檢索之倒排索引實現原理、API解析【2018.11】

》 官網 http://lucene.apache.org/ 下載地址:https://mirrors.tuna.tsinghua.edu.cn/apache/lucene/java/7.5.0/ 》 Lucene的全文檢索是指什麼: 程式掃描文件

使用Lucene對doc、docx、pdf、txt文件進行全文檢索功能的實現

這裡講一下使用Lucene對doc、docx、pdf、txt文件進行全文檢索功能的實現。 涉及到的類一共有兩個: LuceneCreateIndex,建立索引: package com.yhd.test.poi; import java.io.BufferedReader; impo

使用Lucene-Spatial實現整合地理位置的全文檢索

        Lucene通過Spatial包提供了對基於地理位置的全文檢索的支援,最典型的應用場景就是:“搜尋中關村附近1公里內的火鍋店,並按遠近排序”。使用Lucene-Spatial新增對地理位置的支援,和之前普通文字搜尋主要有兩點區別:        1. 將座標資

探索Lucene.Net全文檢索

在CSDN,部落格園找了一番Lucene.Net相關資料後,最後發現還是沒有自己想要的,畢竟lucene.net版本一直在變,這裡我用的是Lucene.Net 3.0的版本,demo是在http://www.dotlucene.net/ 網站裡面找到的。方法很完善,API也

Lucene實現各種常見文件的全文檢索

      Lucene是apache軟體基金會jakarta專案組的一個子專案,是一個開放原始碼的全文檢索引擎工具包,即它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,提供了完整的查詢引擎和索引引擎,部分文字分析引擎。Lucene的目的是為軟體開發人員提供一個簡單