Lucene教程--入门程序详解
?Lucene 入門程序
1?需求
實現一個歌詞搜索系統,通過關鍵字搜索,凡是文件名或文件內容包括關鍵字的文件都要找出來。
注意:該入門程序只對文本文件(.txt)搜索。
2?開發環境
Jdk:1.7.0_72
開發工具:eclipse indigo
Lucene包:
lucene-core-4.10.3.jar
lucene-analyzers-common-4.10.3.jar
lucene-queryparser-4.10.3.jar
其它:
commons-io-2.4.jar
junit-4.9.jar
3?Index索引
3.1?創建數據源目錄
創建數據源目錄F:\develop\lucene\searchsource?,該目錄存放要搜索的原始文件。
3.2?創建索引目錄?
創建索引目錄 F:\develop\lucene\indexdata,該目錄存放創建的索引文件。
3.3?Document和Field
索引的目的是為了搜索,索引前要對搜索的內容創建成Document和Field。
3.4?Document
Document文檔是Lucene搜索的單位,最終要將文檔中的數據展示給用戶,文檔中包括多個Field,在設計文檔對象時,可以將一個Document對應關系數據庫的一條記錄,字段對應Field,但是要注意:Document結構屬于NOSql(非關系),不同的Document包括不同的Field,建議將相同類型數據的Document保持Field一致,方便管理維護,避免將不同類型Field數據融合在一個Document中。
比如:
文件信息Document,Field包括:文件名稱、文件類型、文件大小、文件路徑、文件內容等,避免加入非文件信息Field。
3.4.1?Field屬性
Field是文檔中的域,包括Field名和Field值兩部分,一個文檔可以包括多個Field,Document只是Field的一個承載體,Field值即為要索引的內容,也是要搜索的內容。
1、?是否分析(tokenized)
是:將Field值分析出語匯單元即作分詞處理,將詞進行索引
比如:商品名稱、商品簡介等,這些內容用戶要輸入關鍵字搜索,由于搜索的內容格式大、內容多需要分析后將語匯單元索引。
否:不作分詞處理
比如:商品id、訂單號、身份證號等
2、?是否索引(indexed)
是:將Field分析后的詞或整個Field值進行索引,只有索引方可搜索到。
比如:商品名稱、商品簡介分析后進行索引,訂單號、身份證號不用分析但也要索引,這些將來都要作為查詢條件。
否:不索引無法搜索到
比如:商品id、文件路徑、圖片路徑等,不用作為查詢條件的不用索引。
3、?是否存儲(stored)
是:將Field值存儲在文檔中,存儲在文檔中的Field才可以從Document中獲取
比如:商品名稱、訂單號,凡是將來要從Document中獲取的Field都要存儲。
否:不存儲Field值,不存儲的Field無法通過Document獲取
比如:商品簡介,內容較大不用存儲。如果要向用戶展示商品簡介可以從系統的關系數據庫中獲取商品簡介。
3.4.2?Field常用類型
下邊列出了開發中常用 的Filed類型,注意Field的屬性,根據需求選擇:
?
3.5?IndexWriter和Directory
IndexWriter是索引過程的核心組件,通過IndexWriter可以創建新索引、更新索引、刪除索引操作。IndexWriter需要通過Directory對索引進行存儲操作。
Directory描述了索引的存儲位置,底層封裝了I/O操作,負責對索引進行存儲。它的子類常用的包括FSDirectory(在文件系統存儲索引)、RAMDirectory(在內存存儲索引)。
3.6?索引程序代碼
分析:
確定文檔的各各域的屬性和類型:
文件名稱:不分析、索引、存儲,使用StringField方法
文件路徑:不分析、不索引、存儲,使用StoredField方法
文件大小:分析、索引、存儲,使用LongField方法
文件內容:分析,索引,不存儲,使用TextField方法
代碼如下:
public class IndexTest {// 索引源,即源數據目錄private static String searchSource = "F:\\develop\\lucene\\searchsource";// 索引目標地址private static String indexFolder = "F:\\develop\\lucene\\indexdata";@Testpublic void testCreateIndex() {try {//從目錄中讀取文件內容并創建Document文檔List<Document> docs = IndexUtils.file2Document(searchSource);//創建分析器,standardAnalyzer標準分析器Analyzer standardAnalyzer = new StandardAnalyzer();// 指定索引存儲目錄Directory directory = FSDirectory.open(new File(indexFolder));//創建索引操作配置對象IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_3,standardAnalyzer);// 定義索引操作對象indexWriterIndexWriter indexWriter = new IndexWriter(directory,indexWriterConfig);// 遍歷目錄 下的文件生成的文檔,調用indexWriter方法創建索引for (Document document : docs) {indexWriter.addDocument(document);}// 索引操作流關閉indexWriter.close();} catch (IOException e) {e.printStackTrace();}}}IndexUtils.file2Document()方法定義如下:
// 從文件創建Documentpublic static List<Document> file2Document(String folderPath)throws IOException {List<Document> list = new ArrayList<Document>();File folder = new File(folderPath);if (!folder.isDirectory()) {return null;}// 獲取目錄 中的所有文件File[] files = folder.listFiles();for (File file : files) {//文件名稱String fileName = file.getName();System.out.println(fileName);if (fileName.lastIndexOf(".txt") > 0) {// 文件內容String fileContent = FileUtils.readFileToString(file);//文件路徑String filePath = file.getAbsolutePath();//文件大小long fileSize = FileUtils.sizeOf(file);//創建文檔Document doc = new Document();//創建各各Field域//文件名Field field_fileName = new StringField("fileName", fileName, Store.YES);//文件內容Field field_fileContent = new TextField("fileContent", fileContent, Store.NO);//文件大小Field field_fileSize = new LongField("fileSize", fileSize, Store.YES);//文件路徑Field field_filePath = new StoredField("filePath", filePath, Store.YES);//將各各Field添加到文檔中doc.add(field_fileName);doc.add(field_fileContent);doc.add(field_fileSize);doc.add(field_filePath);list.add(doc);}}return list;}4 Search搜索
4.1 索引結構
Lucene的索引結構為倒排索引,倒排文件或倒排索引是指索引對象是文檔或者文檔集合中的單詞等,用來存儲這些單詞在一個文檔或者一組文檔中的存儲位置,是對文檔或者文檔集合的一種最常用的索引機制。
?
Lucene索引index由若干段(segment)組成,每一段由若干的文檔(document)組成,每一個文檔由若干的域(field)組成,每一個域由若干的項(term)組成。
項是最小的索引單位,如果Field進行分析,可能會分析出多個語匯單元(詞),每個詞就是一個Term項,如果Field不進行分析,整個Field就是一個Term項。
項直接代表了一個字符串以及其在文件中的位置、出現次數等信息。域將項和文檔進行關聯。
4.2 使用Luke查看索引
Luke作為Lucene工具包中的一個工具(http://www.getopt.org/luke/),用于查詢、修改lucene的索引文件。
打開Luke方法:
cmd運行:java ?-jar lukeall-4.10.3.jar
如果需要加載第三方分詞器,如果需要加載第三方分詞器,需通過java.ext.dirs加載jar包:
可簡單的將第三方分詞器和lukeall放在一塊兒,cmd下運行:。
java -Djava.ext.dirs=. -jar lukeall-4.10.3.jar
?
4.3 確定索引目錄
搜索是要從索引中查找,確定索引目錄即上邊創建的索引目錄 F:\develop\lucene\indexdata。
4.4 IndexSearcher和IndexReader
通過IndexSearcher執行搜索,構建IndexSearcher需要IndexReader讀取索引目錄,如下圖:
?
代碼如下:
// 指定 目錄File folder = new File(indexFolder);Directory directory = FSDirectory.open(folder);// indexReaderIndexReader indexReader = DirectoryReader.open(directory);// 定義indexSearcherIndexSearcher indexSearcher = new IndexSearcher(indexReader);需要注意:
Indexreader打開需要耗費很大的系統資源,建議使用一個IndexReader,如果索引進行添加、修改或刪除需要打開新的Reader才可以搜索到。
IndexSearcher搜索方法如下:
?
4.5 搜索程序代碼
public class SearchTest {// 索引目錄地址private static String indexFolder = "F:\\develop\\lucene\\indexdata";//查詢方法@Testpublic void testTermQuery() throws IOException {// 創建查詢對象,根據文件名稱域搜索匹配文件名稱的文檔Query query = new TermQuery(new Term("fileName", "springmvc_test.txt"));// 指定索引目錄Directory directory = FSDirectory.open(new File(indexFolder));// 定義IndexReaderIndexReader reader = DirectoryReader.open(directory);// 創建indexSearcherIndexSearcher indexSearcher = new IndexSearcher(reader);// 執行搜索TopDocs topDocs = indexSearcher.search(query, 100);// 提取搜索結果ScoreDoc[] scoreDocs = topDocs.scoreDocs;System.out.println("共搜索到總記錄數:" + topDocs.totalHits);for (ScoreDoc scoreDoc : scoreDocs) {// 文檔idint docID = scoreDoc.doc;// 得到文檔Document doc = indexSearcher.doc(docID);// 輸出 文件內容IndexUtils.printDocumentOfFile(doc);}}IndexUtils.printDocumentOfFile()方法:
//從文檔中讀取文件內容public static void printDocumentOfFile(Document doc){System.out.println("------------------------------");System.out.println("文件名稱 =" + doc.get("fileName"));System.out.println("文件大小 =" + doc.get("fileSize"));System.out.println("文件內容 =" + doc.get("fileContent"));}4.6 TopDocs
Lucene搜索結果可通過TopDocs遍歷,TopDocs類提供了少量的屬性,如下:
?
注意:
Search方法需要指定匹配記錄數量n:indexSearcher.search(query, n)
TopDocs.totalHits:是匹配索引庫中所有記錄的數量
TopDocs.scoreDocs:匹配相關度高的前邊記錄數組,scoreDocs的長度小于等于search方法指定的參數n
總結
以上是生活随笔為你收集整理的Lucene教程--入门程序详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lucene教程--全文检索技术详解
- 下一篇: Lucene教程--Analyzer分析