1. 程式人生 > >【Lucene4.8教程之一】使用Lucene4.8進行索引及搜尋的基本操作

【Lucene4.8教程之一】使用Lucene4.8進行索引及搜尋的基本操作

在Lucene對文字進行處理的過程中,可以大致分為三大部分:

1、索引檔案:提取文件內容並分析,生成索引

2、搜尋內容:搜尋索引內容,根據搜尋關鍵字得出搜尋結果

3、分析內容:對搜尋詞彙進行分析,生成Quey物件。

注:事實上,除了最基本的完全匹配搜尋以外,其它都需要在搜尋前進行分析。

如不加分析步驟,則搜尋JAVA,是沒有結果的,因為在索引過程中已經將詞彙均轉化為小寫,而此處搜尋時則要求關鍵字完全匹配。

使用了QueryParser類以後,則根據Analyzer的具體實現類,對搜尋詞彙進行分析,如大小寫轉換,java and ant等的搜尋詞解釋等。

一、索引檔案

基本步驟如下:

1、建立索引庫IndexWriter

2、根據檔案建立文件Document

 3、向索引庫中寫入文件內容

package com.ljh.search.index;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

// 1、建立索引庫IndexWriter
// 2、根據檔案建立文件Document
// 3、向索引庫中寫入文件內容

public class IndexFiles {

	public static void main(String[] args) throws IOException {

		String usage = "java IndexFiles"
				+ " [-index INDEX_PATH] [-docs DOCS_PATH] \n\n"
				+ "This indexes the documents in DOCS_PATH, creating a Lucene index"
				+ "in INDEX_PATH that can be searched with SearchFiles";

		String indexPath = null;
		String docsPath = null;
		for (int i = 0; i < args.length; i++) {
			if ("-index".equals(args[i])) {
				indexPath = args[i + 1];
				i++;
			} else if ("-docs".equals(args[i])) {
				docsPath = args[i + 1];
				i++;
			}
		}

		if (docsPath == null) {
			System.err.println("Usage: " + usage);
			System.exit(1);
		}

		final File docDir = new File(docsPath);
		if (!docDir.exists() || !docDir.canRead()) {
			System.out
					.println("Document directory '"
							+ docDir.getAbsolutePath()
							+ "' does not exist or is not readable, please check the path");
			System.exit(1);
		}

		IndexWriter writer = null;
		try {
			// 1、建立索引庫IndexWriter
			writer = getIndexWriter(indexPath);
			index(writer, docDir);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			writer.close();
		}

	}

	private static IndexWriter getIndexWriter(String indexPath)
			throws IOException {

		Directory indexDir = FSDirectory.open(new File(indexPath));

		IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_48,
				new StandardAnalyzer(Version.LUCENE_48));

		IndexWriter writer = new IndexWriter(indexDir, iwc);

		return writer;
	}

	private static void index(IndexWriter writer, File file) throws IOException {

		if (file.isDirectory()) {
			String[] files = file.list();
			if (files != null) {
				for (int i = 0; i < files.length; i++) {
					index(writer, new File(file, files[i]));
				}
			}
		} else {
			// 2、根據檔案建立文件Document
			Document doc = new Document();
			Field pathField = new StringField("path", file.getPath(),
					Field.Store.YES);
			doc.add(pathField);
			doc.add(new LongField("modified", file.lastModified(),
					Field.Store.NO));
			doc.add(new TextField("contents", new FileReader(file)));
			System.out.println("Indexing " + file.getName());
			
			// 3、向索引庫中寫入文件內容
			writer.addDocument(doc);
		}

	}

}

(1)使用“java indexfiles -index d:/index -docs d:/tmp”執行程式,索引d:/tmp中的檔案,並將索引檔案放置到d:/index。

(2)上述生成的索引檔案可以使用Luke進行檢視。目前Luke已遷移至github進行託管。


二、搜尋檔案

1、開啟索引庫IndexSearcher
2、根據關鍵詞進行搜尋
3、遍歷結果並處理

package com.ljh.search.search;

//1、開啟索引庫IndexSearcher
//2、根據關鍵詞進行搜尋
//3、遍歷結果並處理
import java.io.File;
import java.io.IOException;

import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class Searcher {
	public static void main(String[] args) throws IOException {

		String indexPath = null;
		String term = null;
		for (int i = 0; i < args.length; i++) {
			if ("-index".equals(args[i])) {
				indexPath = args[i + 1];
				i++;
			} else if ("-term".equals(args[i])) {
				term = args[i + 1];
				i++;
			}
		}

		System.out.println("Searching " + term + " in " + indexPath);

		// 1、開啟索引庫
		Directory indexDir = FSDirectory.open(new File(indexPath));
		IndexReader ir = DirectoryReader.open(indexDir);
		IndexSearcher searcher = new IndexSearcher(ir);

		// 2、根據關鍵詞進行搜尋
		TopDocs docs = searcher.search(
				new TermQuery(new Term("contents", term)), 20);

		// 3、遍歷結果並處理
		ScoreDoc[] hits = docs.scoreDocs;
		System.out.println(hits.length);
		for (ScoreDoc hit : hits) {
			System.out.println("doc: " + hit.doc + " score: " + hit.score);
		}

		ir.close();

	}

}

三、分析

事實上,除了最基本的完全匹配搜尋以外,其它都需要在搜尋前進行分析。

如不加分析步驟,則搜尋JAVA,是沒有結果的,因為在索引過程中已經將詞彙均轉化為小寫,而此處搜尋時則要求關鍵字完全匹配。

使用了QueryParser類以後,則根據Analyzer的具體實現類,對搜尋詞彙進行分析,如大小寫轉換,java and ant等的搜尋詞解釋等。

分析過程有2個基本步驟:

1、生成QueryParser物件

2、呼叫QueryParser.parse()生成Query()物件。

具體程式碼,將下述程式碼:

		// 2、根據關鍵詞進行搜尋
		TopDocs docs = searcher.search(
				new TermQuery(new Term("contents", term)), 20);
用以下代替:
		// 2、根據關鍵詞進行搜尋
		/*TopDocs docs = searcher.search(
				new TermQuery(new Term("contents", term)), 10);*/
		QueryParser parser = new QueryParser(Version.LUCENE_48, "contents", new SimpleAnalyzer(Version.LUCENE_48));
		Query query = null;
		try {
			query = parser.parse(term);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		TopDocs docs = searcher.search(query, 30);


相關推薦

Lucene4.8教程之一使用Lucene4.8進行索引搜尋基本操作

在Lucene對文字進行處理的過程中,可以大致分為三大部分: 1、索引檔案:提取文件內容並分析,生成索引 2、搜尋內容:搜尋索引內容,根據搜尋關鍵字得出搜尋結果 3、分析內容:對搜尋詞彙進行分析,生成Quey物件。 注:事實上,除了最基本的完全匹配搜尋以外,其它都需要在

OpenCV入門教程之一 OpenCV 2.4.8 +VS2010的開發環境配置

ctx 不能 tail 內存錯誤 mage lease 知識庫 我們 錯誤 目錄(?)[-] 因為讀研期間的研究方向是圖像處理所以淺墨這段時間閉門研究了很多OpenCV和圖像處理相關的知識與內容眼看自己積累到一定的程度了於是決定開始開設這個OpenCV系列專欄總結自己

OpenCV入門教程之一 安裝OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 開發環境配置

毛星雲,網路ID「淺墨」,90後,熱愛遊戲開發、遊戲引擎、計算機圖形、實時渲染等技術,就職於騰訊互娛。 微軟最有價值專家 著作《Windows遊戲程式設計之從零開始》、《OpenCV3程式設計入門》 碩士就讀於南京航空航天大學航天學院(2013級碩士研究生),已於2016年三月畢業。本科

OpenCV入門教程之一 安裝OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 開發環境配置

本系列文章由出品,轉載請註明出處。  寫作當前博文時配套使用的OpenCV版本: 2.4.8、2.4.9、3.0 ( 2014年4月28更新OpenCV 2.4.9的配置。 2014年9月12更新OpenCV 3.0的配置 2014年9月12日本文第

solr基礎教程之一Solr相關知識點串講

Solr是Apache Lucene的一個子專案。Lucene為全文搜尋功能提供了完備的API,但它只作為一個API庫存在,而不能直接用於搜尋。因此,Solr基於Lucene構建了一個完整的搜尋引擎,它可以為搜尋引擎新增文件,對文件內容進行分析,併為使用者提供搜尋功能,在此基礎上提供了一個擴充套件功能,如

Tika基礎教程之一Tika基礎教程

一、快速入門 1、Tika是一個用於文字解釋的框架,其本身並不提供任何的庫用於解釋文字,而是呼叫各種各樣的庫,如POI,PDFBox等。 使用Tika,可以提取檔案中的作者、標題、建立時間、正文等內容,相比於java.io自帶的一些功能(如FileInputStream

Cocos2d-HTML5 開發之一新建HTML5項目簡單闡述與cocos2d/x引擎關系

分公司 文件名 真的 參數 部分 cocos2d-x -c js代碼 防止 真的是有一段時間沒寫博了,這段時間呢,發生的事情真的挺多,另外自己呢也閑來做了一些自己的喜歡的東西,主要做的還是基於Mac系統的Cocoa框架的各種編輯器吧。(對了,今年初也出了自己第二本書《

執行力決定命8集《時間管理,讓工作和生活井井有條》

職場、手段、執行力、加薪、「音頻原文」http://dwz.cn/6sB211大家好,我是林琳笨,今天跟大家一起分享《時間管理,讓工作和生活井井有條》,這個話題不但和工作有關系,也和生活關系也很大。成功人士是事業有成,家庭照顧的很好,工作之余能陪家人過快樂的家庭生活,這不可能只是運氣,也未必是他非常的努力,大

附有安裝包連線mysql 8.0的一些坑包括採用PHP 7.0 連線時報錯Unexpected server respose while doing caching_sha2 auth: 109

連結:https://pan.baidu.com/s/1cMzgEKXb9Cpkjbz9APOhiw 提取碼:ld0x 【mysql 8.0】 注: 此版本使用caching_sha2_password的身份驗證機制。在以往的版本中採用的是mysql_native_passwo

源碼閱讀系列JDK 8 ConcurrentHashMap 源碼分析之 由transfer引發的bug

進一步 輸出 _id 更新 com transfer ase put != 不閱讀源碼就不會發現這個事兒 前段時間在閱讀ConcurrentHashMap源碼,版本JDK 8,目前源碼研究已經告一段落。感謝魯道的ConcurrentHashMap源碼分析文章,讀到文章,感覺

REACT NATIVE 系列教程之一觸控事件的兩種形式與四種TOUCHABLE元件詳解

本文是RN(React Native)系列教程第一篇,當然也要給自己的群做個廣告:  React Native @Himi :126100395  剛建立的群,歡迎一起學習、討論、進步。本文主要講解兩點:1.   PanResponder:觸控事件,用以獲取使用者手指所在螢幕的座標(x,y)或觸發、或滑動、或

CC2530入門教程-05CC2530的串行接口原理與應用

max blog 模式 指數 open != tab bre 就會 第5課 CC2530的串行接口原理與應用 廣東職業技術學院 歐浩源 一、並行通信與串行通信 微控制器與外設之間的數據通信,根據連線結構和傳送方式的不同,可以分為兩種:並行通信和串行通信。

Java動態代理學習Spring AOP基礎之一

tor -1 我們 null exception 文件 cat static 一個   Spring AOP使用的其中一個底層技術就是Java的動態代理技術。Java的動態代理技術主要圍繞兩個類進行的    java.lang.reflect.InvocationHan

CgLib動態代理學習Spring AOP基礎之一

div 目前 .get 不知道 ctu get() 內容 想要 外部依賴   如果不了解JDK中proxy動態代理機制的可以先查看上篇文章的內容:Java動態代理學習【Spring AOP基礎之一】   由於Java動態代理Proxy.newProxyInstance()的

機器學習實戰之一:C++實現K-近鄰演算法KNN

本文不對KNN演算法做過多的理論上的解釋,主要是針對問題,進行演算法的設計和程式碼的註解。 KNN演算法: 優點:精度高、對異常值不敏感、無資料輸入假定。 缺點:計算複雜度高、空間複雜度高。 適用資料範圍:數值型和標稱性。 工作原理:存在一個樣本資料集合,也稱作訓練樣本集,

自繪ListBox之一帶Icon的ListBox控制元件

參考: CListBoxST原始碼 Demo源程式: CIconListBox_demo Demo程式圖片: 使用示例: 手動更改ListBox控制元件的屬性如下,因為以下特性不能通過程式碼動態修改。 m_listbox.AddString(TEXT("123"), ID

zabbix個性化監控之一TCP連線數

一、在被監控端上設定 主要命令: netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 1 netstat -an | awk '/^tcp/ {++S[$NF]} END

菜鳥教程筆記Python3 集合

集合set是一個無序不重複元素的序列。 可以使用{}或者set()函式建立集合。 要點:建立空集合只能使用set(),如果用{}會被認為是建立了空字典。 不同時包含於a和b的元素用a^b表示 注意:字串直接作為set的引數輸入,會認為字串中的每個字元是一個元素。

Zigbee精華教程03Z-Stack協議棧中OSAL層常用API函式

【1】osal_msg_allocate():分配訊息快取。     uint8 * osal_msg_allocate( uint16 len ); 【2】osal_msg_deallocate():回收訊息快取。     uint8 osal_msg_dealloc

WebGL連載教程H5開發3D引擎:TS專案建立和hello_world(新)

在上一篇,我們已經準備好了開發環境(如果你沒有,請返回檢視上一篇)。現在我們來學習一步一步建立一個基於vscode的ts專案工程。(typeScript)vscode和一般的ide區別在於,它不是直接在選單裡新建一個工程。以下內容非常非常的詳細,從無到有,多圖實操,跟著一起做