Apache Lucene(全文檢索引擎)—分詞器

来源:http://www.cnblogs.com/hanyinglong/archive/2016/04/15/5395600.html
-Advertisement-
Play Games

目錄 1. Apache Lucene(全文檢索引擎)—創建索引:http://www.cnblogs.com/hanyinglong/p/5387816.html 2. Apache Lucene(全文檢索引擎)—搜索:http://www.cnblogs.com/hanyinglong/p/53 ...


目錄

  1. Apache Lucene(全文檢索引擎)—創建索引:http://www.cnblogs.com/hanyinglong/p/5387816.html

  2. Apache Lucene(全文檢索引擎)—搜索:http://www.cnblogs.com/hanyinglong/p/5391269.html

  3. Apache Lucene(全文檢索引擎)—分詞器:http://www.cnblogs.com/hanyinglong/p/5395600.html

    本項目Demo已上傳GitHub,歡迎大家fork下載學習:https://github.com/kencery/Lucene_Compass(項目內部有很詳細的註釋)

1.分詞器的作用

  a. 在創建索引的時候需要用到分詞器,在使用字元串搜索的時候也會用到分詞器,並且這兩個地方要使用同一個分詞器,否則可能會搜索不出來結果。

  b. 分詞器(Analyzer)的作用是把一段文本中的詞按規則取出所包含的所有詞,對應的是Analyzer類,這是一個抽象類(public abstract class org.apache.lucene.analysis.Analyzer),切分詞的具體規則是由子類實現的,所以對於不同的語言規則,要有不同的分詞器。

  c.關於分詞器的詳細運行代碼,請在GitHub上下載,下載地址:https://github.com/kencery/Lucene_Compass/tree/master/Lucene_5.5,對應的分支為:lucene_five。

2.英文分詞器的原理

  a.英文的處理流程為:輸入文本,辭彙切分,辭彙過濾(去除停用詞),詞乾提取(形態還原)、大寫轉小寫,結果輸出。

  b. 何為形態還原,意思是:去除單詞詞尾的形態變化,將其還原為詞的原形,這樣做可以搜索出更多有意義的結果,比如在搜索student的時候,同事也可以搜索出students的結果。

  c. 任何一個分詞法對英文的支持都是還可以的。

3.中文分詞器的原理

  a.中文分詞比較複雜,並沒有英文分詞那麼簡單,這主要是因為中文的詞與詞之間並不是像英文那樣用空格來隔開,

因為不是一個字就是一個詞,而且一個詞在另外一個地方就可能不是一個詞,如:"我們是中國人","是中"就不是一個詞,對於中文分詞,通常有三種方式:單字分詞、二分法分詞、詞典分詞。

    a.1 單字分詞:就是按照中文一個字一個字的進行分詞,比如:"我們是中國人",分詞的效果就是"我","們","是","中","國","人",StandardAnalyzer分詞法就是單字分詞。

    a.2 二分法分詞:按照兩個字進行切分,比如:"我們是中國人",分詞的效果就是:"我們","們是","是中","中國","國人",CJKAnalyzer分詞法就是二分法分詞

    a.3 詞庫分詞:按照某種演算法構造詞,然後去匹配已建好的詞庫集合,如果匹配到就切分出來成為詞語,通常詞庫分詞被認為是最好的中文分詞演算法,如:"我們是中國人",分詞的效果就是:"我們","中國人",極易分詞

MMAnalyzer、庖丁分詞、IkAnalyzer等分詞法就是屬於詞庫分詞。

  b.分詞器還有很大,請大家自行查詢,它們的實現基本一致,都是Analyzer的子類,故而可以很完美的繼承到Lucene中。

4.停用詞的規則

  a. 有些詞在文本中出現的頻率非常高,但是對文本所攜帶的信息基本不產生影響,例如英文的"a、an、the、of"或中文的"的、了、著、是",以及各種標點符號等,這樣的詞稱為停用詞,文本經過分詞處理後,停用詞通常會被過濾掉,不會被進行索引,在檢索的時候,用戶的查詢中如果含有停用詞,檢索系統也會將其過濾掉,這是因為用戶輸入哦查詢字元串也要進行分詞處理,排除停用詞可以鹼蕢建立索引的速度,減小索引庫文件的大小。

5.分詞器的使用代碼

  1 package com.lyzj.kencery.unit;
  2 import java.io.StringReader;
  3 import org.apache.lucene.analysis.Analyzer;
  4 import org.apache.lucene.analysis.TokenStream;
  5 import org.apache.lucene.analysis.cjk.CJKAnalyzer;
  6 import org.apache.lucene.analysis.standard.StandardAnalyzer;
  7 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
  8 import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
  9 import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
 10 import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
 11 import org.junit.Test;
 12 import org.wltea.analyzer.lucene.IKAnalyzer;
 13 /**
 14  * 測試分詞器
 15  * 分詞器工作流程
 16  *     1.切分,將需要分詞的內容進行切分成每個單詞或者詞語
 17  *     2.去除停用詞,有些詞在文本中出現的頻率非常高,但是對文本所攜帶的信息基本不產生影響,例如英文的“a、an、the、of”,或中文的“的、了、著、是”,以及各種標點符號等,
 18  * 這樣的詞稱為停用詞(stop word)。文本經過分詞之後,停用詞通常被過濾掉,不會被進行索引。在檢索的時候,用戶的查詢中如果含有停用詞,
 19  * 檢索系統也會將其過濾掉(因為用戶輸入的查詢字元串也要進行分詞處理)。排除停用詞可以加快建立索引的速度,減小索引庫文件的大小。
 20  *     3.對於英文字母,轉為小寫,因為搜索的時候不區分大小寫
 21  * @author kencery
 22  *
 23  */
 24 public class AnalyzerTest {
 25 
 26     /**
 27      * StandardAnalyzer分詞法測試,對中文支持不是很好,將中文分詞成1個字(單字分詞)
 28      * @throws Exception 
 29      */
 30     @Test
 31     public void StandardAnalyzerTest() throws Exception{
 32         //英文測試
 33         String text="An IndexWriter creaters and maintains an index.";
 34         Analyzer analyzer=new StandardAnalyzer();
 35         displayTokens(analyzer,text);
 36         //中文測試
 37         String text1="Lucene是全文檢索框架";
 38         displayTokens(analyzer,text1);    
 39     }
 40 
 41      /**
 42       * CJKAnalyzerTest分詞法測試,對中文支持不是很好,將中文分詞成2個字(二分法分詞)
 43       * 
 44       * @throws Exception
 45       */
 46     @Test
 47     public void CJKAnalyzerTest() throws Exception{
 48         //英文測試
 49         String text="An IndexWriter creaters and maintains an index.";
 50         Analyzer analyzer=new CJKAnalyzer();
 51         displayTokens(analyzer,text);
 52         //中文測試
 53         String text1="Lucene是全文檢索框架";
 54         displayTokens(analyzer,text1);    
 55     }
 56 
 57      /**
 58       * IKAnalyzerTest分詞法測試,對中文支持很好,詞庫分詞
 59       * @throws Exception
 60       */
 61     @Test
 62     public void IKAnalyzerTest() throws Exception{
 63         //英文測試
 64         String text="An IndexWriter creaters and maintains an index.";
 65         Analyzer analyzer=new IKAnalyzer();
 66         displayTokens(analyzer,text);
 67         //中文測試
 68         String text1="韓迎龍易淘食的Lucene是全文檢索框架";
 69         displayTokens(analyzer,text1);    
 70     }
 71 
 72     /**
 73      * 使用指定的分詞器對指定的文本進行分詞,並列印出分出的詞,測試分詞法的方法
 74      * 備註說明:這裡註意版本問題,暫無方法解決
 75      * @param analyzer
 76      * @param text
 77      * @throws Exception
 78      */
 79     public static void displayTokens(Analyzer analyzer, String text) throws Exception {
 80         System.out.println("當前使用的分詞器:" + analyzer.getClass().getName());
 81         //分詞流,即將對象分詞後所得的Token在記憶體中以流的方式存在,也說是說如果在取得Token必須從TokenStream中獲取,而分詞對象可以是文檔文本,也可以是查詢文本。
 82         TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(text));
 83         //表示token的首字母和尾字母在原文本中的位置。比如I'm的位置信息就是(0,3),需要註意的是startOffset與endOffset的差值並不一定就是termText.length(),
 84         //因為可能term已經用stemmer或者其他過濾器處理過;
 85         OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
 86         //這個有點特殊,它表示tokenStream中的當前token與前一個token在實際的原文本中相隔的詞語數量,用於短語查詢。比如: 在tokenStream中[2:a]的前一個token是[1:I'm ],
 87         //它們在原文本中相隔的詞語數是1,則token="a"的PositionIncrementAttribute值為1;
 88         PositionIncrementAttribute positionIncrementAttribute = tokenStream.addAttribute(PositionIncrementAttribute.class);
 89 
 90         //問題說明:這裡需要使用jdk1.7,如果使用jdk1.8或者jdk1.6則會出現報錯信息
 91         //>>如果大家誰有相應的解決方案,請提交到git上我將會合併或者添加我的QQ我們互相討論
 92         CharTermAttribute charTermAttribute= tokenStream.addAttribute(CharTermAttribute.class);
 93 
 94         //表示token詞典類別信息,預設為“Word”,比如I'm就屬於<APOSTROPHE>,有撇號的類型;
 95         TypeAttribute typeAttribute = tokenStream.addAttribute(TypeAttribute.class);
 96         tokenStream.reset();
 97 
 98         int position = 0;
 99         while (tokenStream.incrementToken()) {
100           int increment = positionIncrementAttribute.getPositionIncrement();
101           if(increment > 0) {
102             position = position + increment;
103           }
104           int startOffset = offsetAttribute.startOffset();
105           int endOffset = offsetAttribute.endOffset();
106           String term ="輸出結果為:"+ charTermAttribute.toString();
107           System.out.println("第"+position+"個分詞,分詞內容是:[" + term + "]" + ",分詞內容的開始結束位置為:(" + startOffset + "-->" + endOffset + "),類型是:" + typeAttribute.type());
108         }
109         tokenStream.close();
110     }
111 }

 

6. Compass簡單介紹(不建議使用)

  a. 已經不建議使用,因為官方已停止更新,支持的Lucene的最高版本為2.4,而當前Lucene的版本已經到了5.5。

  b. 因為是學習,所以簡單寫了一個Compass的Demo,下載地址:https://github.com/kencery/Lucene_Compass/tree/master/Compass_2.2,項目內部有詳細的代碼備註。

  c.這裡有一篇別人寫的Compass博客,個人感覺非常好,地址:http://yufenfei.iteye.com/blog/1683546

 

   備註:接下來將使用ElasticSearch來做搜索。

 


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

-Advertisement-
Play Games
更多相關文章
  • 目標網站:http://www.netbian.com/ 目的:實現對壁紙各分類的第一頁壁紙的獲取 一:分析網站,編寫代碼: (ps:源代碼在文章的最後) 1.獲取網站目錄部分的一大段代碼,下一步再進行仔細匹配網址與標題. 如圖: 2.進行分類的標題與鏈接的匹配。 如下圖所示: 3.從爬取到的目錄進 ...
  • 今天碰到一個非常奇怪的問題,機器環境是JDK8、Tomcat8,把jQuery MiniUI ( for Java Eclipse)下載後導入到Eclipse中,首頁可以顯示,但運行操作資料庫的頁面出錯。在該項目下新建一個簡單的jsp頁面,發現也不能運行,出現錯誤提示: org.apache.jas ...
  • 使用python的Flask框架時,參考《Flask Web開發》一書時,發現書中可以在全局使用Permission.FOLLOW變數。 但是自己在嘗試是,確提示變數沒有定義。經過搜索,找到了答案。 在Flask框架中,把變數註冊到全局,有兩個方法: 1、在主app或者藍本中通過裝飾器註冊 2、添加 ...
  • 本文主要針對java反射進行學習,以java.lang.reflect包中的介面和類進行學習和理解。文章目錄如下: 1. java反射概念 2. java反射包介面詳解 3. java發射包中類詳解 4. java反射的應用例子 一:java反射概念 JAVA反射機制是在運行狀態中,對於任意一個類, ...
  • 1、問題使用jQuery的ajax請求 Servlet 時,返回沒有進入ajax的success回調函數,瀏覽器控制台顯示 [HTTP/1.1 405 Method not allowed]。 2、解決方法網上調查,大多都是如下解釋 Apache、IIS、Nginx等絕大多數web伺服器,都不允許靜 ...
  • 1、基本概念 a、路徑和路徑長度 若在一棵樹中存在著一個結點序列 k1,k2,……,kj, 使得 ki是ki+1 的雙親(1<=i<j),則稱此結點序列是從 k1 到 kj 的路徑。 從 k1 到 kj 所經過的分支數稱為這兩點之間的路徑長度,它等於路徑上的結點數減1. b、結點的權和帶權路徑長度 ...
  • 我也是PHP新手,通過w3cschool瞭解了一下php基本原理之後就開寫了。但仍是菜鳥。 先不管3DES加密的方法對不對,方法都是網上的,在運行的時候報了個錯,把小弟整死了。找來找去終於自己摸出了方法。 代碼可以不看,就看裡面的一句:$td = mcrypt_module_open( MCRYPT ...
  • python有很多擴展模塊需要安裝 這個時候萬能的pip就可以提供幫助 首頁進入官網下載壓縮包: https://pypi.python.org/pypi/pip#downloads 解壓文件 cmd進入解壓文件路徑下輸入 python setup.py install 下來要使用pip一定要先進入 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...