忠信篤敬 知行合一 自強不息 和而不同
lucene學習
Lucene 簡介
Lucene 是一個基於 Java 的全文資訊檢索工具包,它不是一個完整的搜尋應用程式,而是為你的應用程式提供索引和搜尋功能。Lucene 目前是 Apache Jakarta 家族中的一個開源專案。也是目前最為流行的基於 Java 開源全文檢索工具包。
目前已經有很多應用程式的搜尋功能是基於 Lucene 的,比如 Eclipse 的幫助系統的搜尋功能。Lucene 能夠為文字型別的資料建立索引,所以你只要能把你要索引的資料格式轉化的文字的,Lucene 就能對你的文件進行索引和搜尋。比如你要對一些 HTML 文件,PDF 文件進行索引的話你就首先需要把 HTML 文件和 PDF 文件轉化成文字格式的,然後將轉化後的內容交給 Lucene 進行索引,然後把建立好的索引檔案儲存到磁碟或者記憶體中,最後根據使用者輸入的查詢條件在索引檔案上進行查詢。不指定要索引的文件的格式也使 Lucene 能夠幾乎適用於所有的搜尋應用程式。
圖 1 表示了搜尋應用程式和 Lucene 之間的關係,也反映了利用 Lucene 構建搜尋應用程式的流程:
圖 1. 搜尋應用程式和 Lucene 之間的關係
索引和搜尋
索引是現代搜尋引擎的核心,建立索引的過程就是把源資料處理成非常方便查詢的索引檔案的過程。為什麼索引這麼重要呢,試想你現在要在大量的文件中搜索含有某個關鍵詞的文件,那麼如果不建立索引的話你就需要把這些文件順序的讀入記憶體,然後檢查這個文章中是不是含有要查詢的關鍵詞,這樣的話就會耗費非常多的時間,想想搜尋引擎可是在毫秒級的時間內查找出要搜尋的結果的。這就是由於建立了索引的原因,你可以把索引想象成這樣一種資料結構,他能夠使你快速的隨機訪問儲存在索引中的關鍵詞,進而找到該關鍵詞所關聯的文件。Lucene 採用的是一種稱為反向索引(inverted index)的機制。反向索引就是說我們維護了一個詞 / 短語表,對於這個表中的每個詞 / 短語,都有一個連結串列描述了有哪些文件包含了這個詞 / 短語。這樣在使用者輸入查詢條件的時候,就能非常快的得到搜尋結果。我們將在本系列文章的第二部分詳細介紹 Lucene 的索引機制,由於 Lucene 提供了簡單易用的 API,所以即使讀者剛開始對全文字進行索引的機制並不太瞭解,也可以非常容易的使用 Lucene 對你的文件實現索引。
對文件建立好索引後,就可以在這些索引上面進行搜尋了。搜尋引擎首先會對搜尋的關鍵詞進行解析,然後再在建立好的索引上面進行查詢,最終返回和使用者輸入的關鍵詞相關聯的文件。
Lucene 軟體包分析
Lucene 軟體包的釋出形式是一個 JAR 檔案,下面我們分析一下這個 JAR 檔案裡面的主要的 JAVA 包,使讀者對之有個初步的瞭解。
Package: org.apache.lucene.document
這個包提供了一些為封裝要索引的文件所需要的類,比如 Document, Field。這樣,每一個文件最終被封裝成了一個 Document 物件。
Package: org.apache.lucene.analysis
這個包主要功能是對文件進行分詞,因為文件在建立索引之前必須要進行分詞,所以這個包的作用可以看成是為建立索引做準備工作。
Package: org.apache.lucene.index
這個包提供了一些類來協助建立索引以及對建立好的索引進行更新。這裡面有兩個基礎的類:IndexWriter 和 IndexReader,其中 IndexWriter 是用來建立索引並新增文件到索引中的,IndexReader 是用來刪除索引中的文件的。
Package: org.apache.lucene.search
這個包提供了對在建立好的索引上進行搜尋所需要的類。比如 IndexSearcher 和 Hits, IndexSearcher 定義了在指定的索引上進行搜尋的方法,Hits 用來儲存搜尋得到的結果。
一個簡單的搜尋應用程式
假設我們的電腦的目錄中含有很多文字文件,我們需要查詢哪些文件含有某個關鍵詞。為了實現這種功能,我們首先利用 Lucene 對這個目錄中的文件建立索引,然後在建立好的索引中搜索我們所要查詢的文件。通過這個例子讀者會對如何利用 Lucene 構建自己的搜尋應用程式有個比較清楚的認識。
建立索引
為了對文件進行索引,Lucene 提供了五個基礎的類,他們分別是 Document, Field, IndexWriter, Analyzer, Directory。下面我們分別介紹一下這五個類的用途:
Document
Document 是用來描述文件的,這裡的文件可以指一個 HTML 頁面,一封電子郵件,或者是一個文字檔案。一個 Document 物件由多個 Field 物件組成的。可以把一個 Document 物件想象成資料庫中的一個記錄,而每個 Field 物件就是記錄的一個欄位。
Field
Field 物件是用來描述一個文件的某個屬性的,比如一封電子郵件的標題和內容可以用兩個 Field 物件分別描述。
Analyzer
在一個文件被索引之前,首先需要對文件內容進行分詞處理,這部分工作就是由 Analyzer 來做的。Analyzer 類是一個抽象類,它有多個實現。針對不同的語言和應用需要選擇適合的 Analyzer。Analyzer 把分詞後的內容交給 IndexWriter 來建立索引。
IndexWriter
IndexWriter 是 Lucene 用來建立索引的一個核心的類,他的作用是把一個個的 Document 物件加到索引中來。
Directory
這個類代表了 Lucene 的索引的儲存的位置,這是一個抽象類,它目前有兩個實現,第一個是 FSDirectory,它表示一個儲存在檔案系統中的索引的位置。第二個是 RAMDirectory,它表示一個儲存在記憶體當中的索引的位置。
熟悉了建立索引所需要的這些類後,我們就開始對某個目錄下面的文字檔案建立索引了,清單 1 給出了對某個目錄下的文字檔案建立索引的原始碼。
清單 1. 對文字檔案建立索引
package TestLucene;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.util.Date;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
/**
* This class demonstrate the process of creating index with Lucene
* for text files
*/
public class TxtFileIndexer {
public static void main(String[] args) throws Exception{
//indexDir is the directory that hosts Lucene's index files
File indexDir = new File("D:\\luceneIndex");
//dataDir is the directory that hosts the text files that to be indexed
File dataDir = new File("D:\\luceneData");
Analyzer luceneAnalyzer = new StandardAnalyzer();
File[] dataFiles = dataDir.listFiles();
IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
long startTime = new Date().getTime();
for(int i = 0; i < dataFiles.length; i++){
if(dataFiles[i].isFile() && dataFiles[i].getName().endsWith(".txt")){
System.out.println("Indexing file " + dataFiles[i].getCanonicalPath());
Document document = new Document();
Reader txtReader = new FileReader(dataFiles[i]);
document.add(Field.Text("path",dataFiles[i].getCanonicalPath()));
document.add(Field.Text("contents",txtReader));
indexWriter.addDocument(document);
}
}
indexWriter.optimize();
indexWriter.close();
long endTime = new Date().getTime();
System.out.println("It takes " + (endTime - startTime)
+ " milliseconds to create index for the files in directory "
+ dataDir.getPath());
}
}
在清單 1 中,我們注意到類 IndexWriter 的建構函式需要三個引數,第一個引數指定了所建立的索引要存放的位置,他可以是一個 File 物件,也可以是一個 FSDirectory 物件或者 RAMDirectory 物件。第二個引數指定了 Analyzer 類的一個實現,也就是指定這個索引是用哪個分詞器對文擋內容進行分詞。第三個引數是一個布林型的變數,如果為 true 的話就代表建立一個新的索引,為 false 的話就代表在原來索引的基礎上進行操作。接著程式遍歷了目錄下面的所有文字文件,併為每一個文字文件建立了一個 Document 物件。然後把文字文件的兩個屬性:路徑和內容加入到了兩個 Field 物件中,接著在把這兩個 Field 物件加入到 Document 物件中,最後把這個文件用 IndexWriter 類的 add 方法加入到索引中去。這樣我們便完成了索引的建立。接下來我們進入在建立好的索引上進行搜尋的部分。
搜尋文件
利用 Lucene 進行搜尋就像建立索引一樣也是非常方便的。在上面一部分中,我們已經為一個目錄下的文字文件建立好了索引,現在我們就要在這個索引上進行搜尋以找到包含某個關鍵詞或短語的文件。Lucene 提供了幾個基礎的類來完成這個過程,它們分別是呢 IndexSearcher, Term, Query, TermQuery, Hits. 下面我們分別介紹這幾個類的功能。
Query
這是一個抽象類,他有多個實現,比如 TermQuery, BooleanQuery, PrefixQuery. 這個類的目的是把使用者輸入的查詢字串封裝成 Lucene 能夠識別的 Query。
Term
Term 是搜尋的基本單位,一個 Term 物件有兩個 String 型別的域組成。生成一個 Term 物件可以有如下一條語句來完成:Term term = new Term(“fieldName”,”queryWord”); 其中第一個引數代表了要在文件的哪一個 Field 上進行查詢,第二個引數代表了要查詢的關鍵詞。
TermQuery
TermQuery 是抽象類 Query 的一個子類,它同時也是 Lucene 支援的最為基本的一個查詢類。生成一個 TermQuery 物件由如下語句完成: TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”)); 它的建構函式只接受一個引數,那就是一個 Term 物件。
IndexSearcher
IndexSearcher 是用來在建立好的索引上進行搜尋的。它只能以只讀的方式開啟一個索引,所以可以有多個 IndexSearcher 的例項在一個索引上進行操作。
Hits
Hits 是用來儲存搜尋的結果的。
介紹完這些搜尋所必須的類之後,我們就開始在之前所建立的索引上進行搜尋了,清單 2 給出了完成搜尋功能所需要的程式碼。
清單 2 :在建立好的索引上進行搜尋
package TestLucene;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.util.Date;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
/**
* This class demonstrate the process of creating index with Lucene
* for text files
*/
public class TxtFileIndexer {
public static void main(String[] args) throws Exception{
//indexDir is the directory that hosts Lucene's index files
File indexDir = new File("D:\\luceneIndex");
//dataDir is the directory that hosts the text files that to be indexed
File dataDir = new File("D:\\luceneData");
Analyzer luceneAnalyzer = new StandardAnalyzer();
File[] dataFiles = dataDir.listFiles();
IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
long startTime = new Date().getTime();
for(int i = 0; i < dataFiles.length; i++){
if(dataFiles[i].isFile() && dataFiles[i].getName().endsWith(".txt")){
System.out.println("Indexing file " + dataFiles[i].getCanonicalPath());
Document document = new Document();
Reader txtReader = new FileReader(dataFiles[i]);
document.add(Field.Text("path",dataFiles[i].getCanonicalPath()));
document.add(Field.Text("contents",txtReader));
indexWriter.addDocument(document);
}
}
indexWriter.optimize();
indexWriter.close();
long endTime = new Date().getTime();
System.out.println("It takes " + (endTime - startTime)
+ " milliseconds to create index for the files in directory "
+ dataDir.getPath());
}
}
在清單 1 中,我們注意到類 IndexWriter 的建構函式需要三個引數,第一個引數指定了所建立的索引要存放的位置,他可以是一個 File 物件,也可以是一個 FSDirectory 物件或者 RAMDirectory 物件。第二個引數指定了 Analyzer 類的一個實現,也就是指定這個索引是用哪個分詞器對文擋內容進行分詞。第三個引數是一個布林型的變數,如果為 true 的話就代表建立一個新的索引,為 false 的話就代表在原來索引的基礎上進行操作。接著程式遍歷了目錄下面的所有文字文件,併為每一個文字文件建立了一個 Document 物件。然後把文字文件的兩個屬性:路徑和內容加入到了兩個 Field 物件中,接著在把這兩個 Field 物件加入到 Document 物件中,最後把這個文件用 IndexWriter 類的 add 方法加入到索引中去。這樣我們便完成了索引的建立。接下來我們進入在建立好的索引上進行搜尋的部分。
搜尋文件
利用 Lucene 進行搜尋就像建立索引一樣也是非常方便的。在上面一部分中,我們已經為一個目錄下的文字文件建立好了索引,現在我們就要在這個索引上進行搜尋以找到包含某個關鍵詞或短語的文件。Lucene 提供了幾個基礎的類來完成這個過程,它們分別是呢 IndexSearcher, Term, Query, TermQuery, Hits. 下面我們分別介紹這幾個類的功能。
Query
這是一個抽象類,他有多個實現,比如 TermQuery, BooleanQuery, PrefixQuery. 這個類的目的是把使用者輸入的查詢字串封裝成 Lucene 能夠識別的 Query。
Term
Term 是搜尋的基本單位,一個 Term 物件有兩個 String 型別的域組成。生成一個 Term 物件可以有如下一條語句來完成:Term term = new Term(“fieldName”,”queryWord”); 其中第一個引數代表了要在文件的哪一個 Field 上進行查詢,第二個引數代表了要查詢的關鍵詞。
TermQuery
TermQuery 是抽象類 Query 的一個子類,它同時也是 Lucene 支援的最為基本的一個查詢類。生成一個 TermQuery 物件由如下語句完成: TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”)); 它的建構函式只接受一個引數,那就是一個 Term 物件。
IndexSearcher
IndexSearcher 是用來在建立好的索引上進行搜尋的。它只能以只讀的方式開啟一個索引,所以可以有多個 IndexSearcher 的例項在一個索引上進行操作。
Hits
Hits 是用來儲存搜尋的結果的。
介紹完這些搜尋所必須的類之後,我們就開始在之前所建立的索引上進行搜尋了,清單 2 給出了完成搜尋功能所需要的程式碼。
清單 2 :在建立好的索引上進行搜尋
package TestLucene;
import java.io.File;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.FSDirectory;
/**
* This class is used to demonstrate the
* process of searching on an existing
* Lucene index
*
*/
public class TxtFileSearcher {
public static void main(String[] args) throws Exception{
String queryStr = "lucene";
//This is the directory that hosts the Lucene index
File indexDir = new File("D:\\luceneIndex");
FSDirectory directory = FSDirectory.getDirectory(indexDir,false);
IndexSearcher searcher = new IndexSearcher(directory);
if(!indexDir.exists()){
System.out.println("The Lucene index is not exist");
return;
}
Term term = new Term("contents",queryStr.toLowerCase());
TermQuery luceneQuery = new TermQuery(term);
Hits hits = searcher.search(luceneQuery);
for(int i = 0; i < hits.length(); i++){
Document document = hits.doc(i);
System.out.println("File: " + document.get("path"));
}
}
}
在清單 2 中,類 IndexSearcher 的建構函式接受一個型別為 Directory 的物件,Directory 是一個抽象類,它目前有兩個子類:FSDirctory 和 RAMDirectory. 我們的程式中傳入了一個 FSDirctory 物件作為其引數,代表了一個儲存在磁碟上的索引的位置。建構函式執行完成後,代表了這個 IndexSearcher 以只讀的方式打開了一個索引。然後我們程式構造了一個 Term 物件,通過這個 Term 物件,我們指定了要在文件的內容中搜索包含關鍵詞”lucene”的文件。接著利用這個 Term 物件構造出 TermQuery 物件並把這個 TermQuery 物件傳入到 IndexSearcher 的 search 方法中進行查詢,返回的結果儲存在 Hits 物件中。最後我們用了一個迴圈語句把搜尋到的文件的路徑都列印了出來。 好了,我們的搜尋應用程式已經開發完畢,怎麼樣,利用 Lucene 開發搜尋應用程式是不是很簡單。
總結
本文首先介紹了 Lucene 的一些基本概念,然後開發了一個應用程式演示了利用 Lucene 建立索引並在該索引上進行搜尋的過程。希望本文能夠為學習 Lucene 的讀者提供幫助。
相關推薦
忠信篤敬 知行合一 自強不息 和而不同
lucene學習 Lucene 簡介 Lucene 是一個基於 Java 的全文資訊檢索工具包,它不是一個完整的搜尋應用程式,而是為你的應用程式提供索引和搜尋功能。Lucene 目前是 Apache Jakarta 家族中的一個開源專案。也是目前最為
更上一層樓!(海納百川、自強不息、厚德篤學、知行合一 -- 大連理工大學)
Lucene&Compass搜尋框架 Lucene是一款Apache頂級專案,在全文搜尋方面做得很好。而Compass是基於Lucene的一款二次封裝的更加易用的搜尋框架。我們可以基於這兩個框架做出適合我們自己專案的站內搜
知行合一
tar 運用 target 客體 王陽明 現實 便是 命題 並行 http://www.baike.com/wiki/知行合一 知行合一,是指客體順應主體,知是指科學知識,行是指人的實踐,知與行的合一,既不是以知來吞並行,認為知便是行,也不是以行來吞並知,認為行便是知。是明
讀書筆記 - 《王陽明大傳:知行合一的心學智慧》
掌握 能夠 價值 介紹 詳細 開始 記得 不知道 信念 已經不記得是什麽時候開始讀這套書,直到今天才終於初步完成,這真是一段艱苦的心靈旅程。 作為陽明學和王陽明研究的大師,作者在書中巨細靡遺的介紹了王陽明有記載的所有活動和事件,摻雜大量原古文和詩文,對於詳細的時間和事件的細
近期辦事犯錯總結-知行合一、知在行前-解決問題前,首先要搞清楚問題
審核 blog 部門 pos body 區別 居住 老婆 流程 事件一:辦卡出錯 幫老婆去辦卡。老婆給了辦卡流程,然後按照流程去辦理。 中間跳過很多環節; 在直接辦卡環節,告訴工作人員我要辦卡,工作人員確認“你要辦卡嗎?”,我說是; 結果悲劇出現了,辦卡人員錄入身份證號後告
上海世基——知行合一培訓
就是 上海 人做 其實在 python 學習 多人 其他 方法 傑鍋說,90%的人做股票虧錢的原因是沒有知行合一,許許多多的人都是各自有自己的方法選股賣股,但是還是虧錢的,原因就是沒有真正的執行力。 很多人都有使用黃藍帶,但是藍賣並沒有嚴格執行,導致在市場虧錢。虧錢了舍不得
《知行合一 王陽明》讀後感悟
該書作者為度陰山,主要講述了我國明朝時期心學家王陽明(王守仁)的人生歷程和陽明心學的來源及“修煉”法門。通讀全書,給我留下印象最深的幾個詞語是“知行合一”、“致良知”、“心即理”及王陽明晚年對自己心學的歸納“四句教”。陽明心學,用現代的話總結就是用良知的心作為
【知行合一】厚積薄發,格物致知。簡單點,做事的動機簡單點。
關於博主 目前主要學習機器人導航與定位演算法: 基本掌握filter-slam,graph-slam框架,熟悉單目tracking部分的direct method 和 feature method. 熟悉單目mapping部分的深度估計,正在努力學習semi-dense
江南孤鶩——“知行合一”的Software Developer
解決方案 首先,用絕對定位以及z-index將div至於最底部: position: absolute; z-index:-999; 然後,讓絕對定位的div水平居中。使用負外
GAMELOFT9----讀萬卷書,行萬里路,知行合一
Deferred物件是由$.Deferred構造的,$.Deferred被實現為簡單工廠模式。 它用來解決JS中的非同步程式設計,它遵循 Common Promise/A 規範。實現此規範的還有 when.js 和 dojo。 $.Deferred作為
漫談 · 比知行合一更重要的是意行合一
本文來源於本人微信公眾號:https://mp.weixin.qq.com/s/g8Tdi20gPhyAPq-W_-k6gw 人生修行在於不斷的提升自己的認知,並達到認知和行為的一致性。這就是所謂的知行合一。 知行合一,本就是非常困難的。在於認知的提升
從“讀萬卷書”到“行萬里路”,如何做到知行合一
生活不是抽象任性的美好暢想,是具體而細微的實際行動。讓自己慢下來,從容做事,優雅生活,這才是生活的最終目的。 ——吳軍 一、我們為什麼要閱讀 現在是一個電子媒體高度發達的時代,尤其內容展示的方式上是非常豐富的。在這種情況下,人真正用來讀文字的時間相對是減少的。 如今,很多人慢慢都
碼路,心路,知行合一。
Java加解密 實現方式:JDK實現,CC,BC JDK提供比較基礎的底層的實現;CC提供一些簡化的操作;BC提供補充 一、Base64加密 非常簡單,加密解密就一個函式。 程式碼如下: public static void jdkBase64() { try {
因為專註 所以專業 知行合一
工具 理解 感謝 power 還得 秘書 自己 pow cmd 因為專註 所以專業 知行合一 還有很多WINDOWS 功能 和工具 不知道, 能把系統平臺 學好 已經非常不錯了。 美國的DON JONES 大半輩子 把 CMD 和POWERSHELL 搞清楚 非
知行在線——做國內一流的企業信息化服務提供商
軟件開發知行在線——做國內一流的企業信息化服務提供商知行在線科技集團旗下包括北京知行在線科技有限公司、保定諾金軟件開發有限公司、秦皇島市曦園文化傳播有限公司、秦皇島龍堯文化傳播有限公司五家子公司。立足京津冀,服務全中國,致力於為國內傳統企業信息化轉型提供全套解決方案。知行在線奉行客戶至上的原則,在國內領先推出
iOS微信支付demo運行報錯解決如下
art llb readme ring -objc override 項目 技術 cep 要接入微信支付的小夥伴,首先要下載一份官方demo(APP微信支付官方Demo下載),然後打開工程,準備大幹一場。 1、編譯報錯 編譯的時候居然直接報錯了(orz) 錯誤提示:
《Scrum實戰》讀書會作業01 - 用知行視角總結現在或者過去的一個項目
style 溝通 架構師 學習型 pri 領域 nbsp 產品線 架構 下面是《Scrum實戰》讀書會的第1個作業,主要是用知行視角來總結回顧現在或者過去的一個項目。 項目背景 2011年初,我做的項目是一個搜索引擎相關的項目,這個項目為公司在全球範圍內的金
Inxi:一個功能強大的獲取Linux系統信息的命令行工具
linux查看系統配置Inxi 最初是為控制臺和 IRC(網絡中繼聊天)開發的一個強大且優秀的命令行系統信息腳本。可以使用它獲取用戶的硬件和系統信息,它也用於調試或者社區技術支持工具。使用 Inxi 可以很容易的獲取所有的硬件信息:硬盤、聲卡、顯卡、網卡、CPU 和 RAM 等。同時也能夠獲取大量的操作系統
SQL Server 執行計劃利用統計信息對數據行的預估原理二(為什麽復合索引列順序會影響到執行計劃對數據行的預估)
pan new statistic 細心 參考 gin 技術分享 重建 target 本文出處:http://www.cnblogs.com/wy123/p/6008477.html 關於統計信息對數據行數做預估,之前寫過對非相關列(單獨或者單獨的索
文遠知行WeRide的技術創新和商業動作
景馳在2018年10月31日改名為文遠知行WeRide,並在“明日之星”的評選中脫穎而出,在其推文中可以看到文遠知行的兩大核心競爭力。 1、技術創新 作為中國領先的L4級別無人駕駛出行公司,文遠知行WeRide在不斷地突破自動駕駛技術上的難題。 在解決長尾場景方面,文遠知行WeRid