1. 程式人生 > >Lucene介紹及簡單入門案例(集成ik分詞器)

Lucene介紹及簡單入門案例(集成ik分詞器)

chinese depend 創建索引 圖片 latest frame numeric id字段 div

介紹  

  Lucene是apache軟件基金會4 jakarta項目組的一個子項目,是一個開放源代碼的全文檢索引擎工具包,但它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,提供了完整的查詢引擎和索引引擎,部分文本分析引擎(英文與德文兩種西方語言)。Lucene的目的是為軟件開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎。Lucene是一套用於全文檢索和搜尋的開源程式庫,由Apache軟件基金會支持和提供。Lucene提供了一個簡單卻強大的應用程式接口,能夠做全文索引和搜尋。在Java開發環境裏Lucene是一個成熟的免費開源工具。就其本身而言,Lucene是當前以及最近幾年最受歡迎的免費Java信息檢索程序庫。人們經常提到信息檢索程序庫,雖然與搜索引擎有關,但不應該將信息檢索程序庫與搜索引擎相混淆。

  Lucene是Apache提供的一個開源的全文檢索引擎工具包, 其本質就是一個工具包, 而非一個完整的搜索引擎, 但是我們可以通過Lucene來構建一個搜索引擎,比如solr和elasticsearch都是基於Lucene的搜索引擎。

使用Lucene如何構建索引

第一步:導入相關的jar包

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-core</artifactId>
    <version
>4.10.2</version> </dependency> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-queries</artifactId> <version>4.10.2</version> </dependency> <dependency> <groupId>org.apache.lucene</groupId
> <artifactId>lucene-test-framework</artifactId> <version>4.10.2</version> </dependency> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-analyzers-common</artifactId> <version>4.10.2</version> </dependency> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-queryparser</artifactId> <version>4.10.2</version> </dependency> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-highlighter</artifactId> <version>4.10.2</version> </dependency>

第二步:書寫寫入索引的代碼

技術分享圖片

簡單案例:

public class LuceneIndex {
    public static void main(String[] args) throws IOException {
        //1 創建indexwriter對象
        //1.1 創建索引庫
        FSDirectory directory = FSDirectory.open(new File("H:\\test"));
        //1.2 創建寫入器配置對象 參數1 版本號, 參數2 分詞器
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, new StandardAnalyzer());
        //1.3 創建indexwriter對象
        IndexWriter indexWriter = new IndexWriter(directory, config);

        //2 寫入文檔
        //2.1 創建文檔對象(lucene的document對象)
        Document document = new Document();
        //2.2 添加文檔屬性(字段)   new xxxField(字段名,字段值,是否保存)
        document.add(new IntField("id", 1, Field.Store.YES));
        document.add(new StringField("title", "Lucene介紹", Field.Store.YES));
        document.add(new TextField("content", "Lucene是一個全文檢索的工具包", Field.Store.YES));
        //2.3 寫入文檔
        indexWriter.addDocument(document);

        //3 提交數據
        indexWriter.commit();

        //釋放資源
        indexWriter.close();
    }
}

使用索引查看工具查看插入的索引信息

下載一個lukeall-xxxx(版本信息).jar, cmd運行這個工具jar包:

技術分享圖片

技術分享圖片

技術分享圖片

Lucene集成IKAnalyzer 中文分詞器

Analyzer: 分詞器:

?   用於對文檔中的數據進行分詞, 其分詞的效果取決於分詞器的選擇, Lucene中根據各個國家制定了各種語言的分詞器,對中文有一個ChineseAnalyzer 但是其分詞的效果, 是將中文進行一個一個字的分開

針對中文分詞一般只能使用第三方的分詞詞,比如IKAnalyzer

首先要引入jar包:

<!-- 引入IK分詞器 -->
<dependency>
    <groupId>com.janeluo</groupId>
    <artifactId>ikanalyzer</artifactId>
    <version>2012_u6</version>
</dependency>

代碼部分只需要修改我們上面案例的分詞器對象即可:

//1.2 創建寫入器配置對象 參數1 版本號, 參數2 分詞器
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, new IKAnalyzer());

高級使用:

ik分詞器在2012年更新後, 就在沒有更新, 其原因就取決於其強大的擴展功能,以保證ik能夠持續使用

  ik支持對自定義詞庫, 其可以定義兩個擴展的詞典

    1) 擴展詞典(新創建詞功能):有些詞IK分詞器不識別 例如:“劍來”,“劍九黃”

    2) 停用詞典(停用某些詞功能)有些詞不需要建立索引 例如:“哦”,“啊”,“的”

如何使用:

技術分享圖片

在resources內創建者三個文件,在ext.dic中設置需要進行分詞的內容即可, 在stopword中設置不被分詞的內容即可,xml文件內容格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
<properties>  
    <comment>IK Analyzer 擴展配置</comment>
    <!--用戶可以在這裏配置自己的擴展字典 -->
    <entry key="ext_dict">ext.dic;</entry> 
    
    <!--用戶可以在這裏配置自己的擴展停止詞字典-->
    <entry key="ext_stopwords">stopword.dic;</entry> 
    
</properties>

其他兩個詞典內容格式:

劍來
劍九黃
劍開天門

API詳解:

  • IndexWriter: 索引寫入器對象

    其主要的作用, 添加索引, 修改索引和刪除索引

    • 創建此對象的時候, 需要傳入Directory和indexWriterConfig對象

  • Directory: 目錄類, 用來指定索引庫的目錄

    • 常用的實現類:

      • FSDirectory: 用來指定文件系統的目錄, 將索引信息保存到磁盤上

        • 優點: 索引可以進行長期保存, 安全系數高

        • 缺點: 讀取略慢

      • RAMDriectory: 內存目錄, 將索引庫信息存放到內存中

        • 優點: 讀取速度快

        • 缺點: 不安全, 無法長期保存, 關機後就消失了

  • IndexWriterConfig: 索引寫入器的配置類

    • 創建此對象, 需要傳遞Lucene的版本和分詞器

    • 作用:

      • 作用1 : 指定Lucene的版本和需要使用的分詞器

      • 作用2: 設置Lucene的打開索引庫的方式: setOpenMode();

//參數值: APPEND CREATE   CREATE_OR_APPEND
/**
 * APPEND: 表示追加, 如果索引庫存在, 就會向索引庫中追加數據, 如果索引庫不存在, 直接報錯
 * 
 * CREATE: 表示創建, 不管索引庫有沒有, 每一次都是重新創建一個新的索引庫
 * 
 * CREATE_OR_APPEND: 如果索引庫有, 就會追加, 如果沒有 就會創建索引庫
         默認值也是 CREATE_OR_APPEND
 */
config.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
  • Document: 文檔

?     在Lucene中, 每一條數據以文檔的形式進行存儲, 文檔中也有其對應的屬性和值, Lucene中一個文檔類似數據庫的一個表, 表中的字段類似於文檔中的字段,只不過這個文檔只能保存一條數據

?     Document看做是一個文件, 文件的屬性就是文檔的屬性, 文件對應屬性的值就是文檔的屬性的值 content

  • 一個文檔中可以有多個字段, 每一個字段就是一個field對象,不同的文檔可以有不同的屬性

  • 字段也有其對應數據類型, 故Field類也提供了各種數據類型的實現類

Field類數據類型Analyzed是否分析Indexed是否索引Stored是否存儲說明
StringField(FieldName, FieldValue,Store.YES)) 字符串 N Y Y或N 這個Field用來構建一個字符串Field,但是不會進行分析,會將整個串存儲在索引中,比如(訂單號,姓名等)是否存儲在文檔中用Store.YES或Store.NO決定
LongField(FieldName, FieldValue,Store.YES) Long型 Y Y Y或N 這個Field用來構建一個Long數字型Field,進行分析和索引,比如(價格)是否存儲在文檔中用Store.YES或Store.NO決定
StoredField(FieldName, FieldValue) 重載方法,支持多種類型 N N Y 這個Field用來構建不同類型Field不分析,不索引,但要Field存儲在文檔中
TextField(FieldName, FieldValue, Store.NO)或TextField(FieldName, reader) 字符串或流 Y Y Y或N 如果是一個Reader, lucene猜測內容比較多,會采用Unstored的策略.

更改和刪除索引:

    /**
     * 更新索引
     * 本質先刪除再添加
     * 先刪除所有滿足條件的文檔,再創建文檔
     * 因此,更新索引通常要根據唯一字段
     */
    @Test
    public void testUpdate() throws Exception {

        // 創建更改後的文檔對象
        Document document = new Document();
        document.add(new StringField("id", "3", Field.Store.YES));
        document.add(new TextField("title", "更改後的titlek", Field.Store.YES));

        // 索引庫對象
        Directory directory = FSDirectory.open(new File("H:\\test"));
        // 索引寫入器配置對象
        IndexWriterConfig conf = new IndexWriterConfig(Version.LATEST, new IKAnalyzer());
        // 索引寫入器對象
        IndexWriter indexWriter = new IndexWriter(directory, conf);

        // 執行更新操作 參數1 要更改的對象, 參數2 更改後的對象
        indexWriter.updateDocument(new Term("id", "1"), document);
        // 提交
        indexWriter.commit();
        // 關閉
        indexWriter.close();

    }

    // 刪除索引
    @Test
    public void testDelete() throws Exception {

        // 創建目錄對象
        Directory directory = FSDirectory.open(new File("H:\\test"));
        // 創建索引寫入器配置對象
        IndexWriterConfig conf = new IndexWriterConfig(Version.LATEST, new IKAnalyzer());
        // 創建索引寫入器對象
        IndexWriter indexWriter = new IndexWriter(directory, conf);

        // 執行刪除操作(根據詞條),要求id字段必須是字符串類型
        indexWriter.deleteDocuments(new Term("id", "5"));
        // 根據查詢條件刪除
        // indexWriter.deleteDocuments(NumericRangeQuery.newLongRange("id", 2l, 4l, true, false));
        // 刪除所有
        //indexWriter.deleteAll();

        // 提交
        indexWriter.commit();
        // 關閉
        indexWriter.close();
    }

Lucene介紹及簡單入門案例(集成ik分詞器)