成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Lucene學(xué)習(xí)筆記

justCoding / 2802人閱讀

摘要:全文檢索概述數(shù)據(jù)分類結(jié)構(gòu)化數(shù)據(jù)具有固定格式或者長(zhǎng)度有限的數(shù)據(jù),例如數(shù)據(jù)庫(kù)中的表。語(yǔ)句非結(jié)構(gòu)化數(shù)據(jù)與結(jié)構(gòu)化數(shù)據(jù)對(duì)立,例如郵件網(wǎng)頁(yè)文檔。

全文檢索概述 數(shù)據(jù)分類

結(jié)構(gòu)化數(shù)據(jù):具有固定格式或者長(zhǎng)度有限的數(shù)據(jù),例如數(shù)據(jù)庫(kù)中的表?!維QL語(yǔ)句】

非結(jié)構(gòu)化數(shù)據(jù):與結(jié)構(gòu)化數(shù)據(jù)對(duì)立,例如:郵件、網(wǎng)頁(yè)、word文檔。【數(shù)據(jù)掃描、全文檢索】

半結(jié)構(gòu)化數(shù)據(jù):介于兩者之間,例如xml或者json格式的數(shù)據(jù)。

全文檢索過程


反向索引(倒排表):由字符串到文件的映射是文件到字符串映射的反向過程。

索引創(chuàng)建

索引檢索

Lucene數(shù)學(xué)模型 文檔、域、詞元

文檔是Lucene搜索和索引的原子單位,文檔為包含一個(gè)或者多個(gè)的容器,而域則是依次包含“真正的”被搜索的內(nèi)容,域值通過分詞技術(shù)處理,得到多個(gè)詞元。

For Example,一篇小說(斗破蒼穹)信息可以稱為一個(gè)文檔,小說信息又包含多個(gè)域,例如:標(biāo)題(斗破蒼穹)、作者、簡(jiǎn)介、最后更新時(shí)間等等,對(duì)標(biāo)題這個(gè)域采用分詞技術(shù)又可以得到一個(gè)或者多個(gè)詞元(斗、破、蒼、穹)。

詞元權(quán)重計(jì)算

Term Frequency(tf):此term在文檔中出現(xiàn)的次數(shù),tf越大則該詞元越重要。

Document Frequency(df):有多少文檔包含此term,df越大該詞元越不重要。

空間向量模型如下:

計(jì)算夾角的余弦值,夾角越小,余弦值越大,分值越大,從而相關(guān)性越大。

Lucene文件結(jié)構(gòu) 層次結(jié)構(gòu)

index:一個(gè)索引存放在一個(gè)目錄中;

segment:一個(gè)索引中可以有多個(gè)段,段與段之間是獨(dú)立的,添加新的文檔可能產(chǎn)生新段,不同的段可以合并成一個(gè)新段;

document:文檔是創(chuàng)建索引的基本單位,不同的文檔保存在不同的段中,一個(gè)段可以包含多個(gè)文檔;

field:域,一個(gè)文檔包含不同類型的信息,可以拆分開索引;

term:詞,索引的最小單位,是經(jīng)過詞法分析和語(yǔ)言處理后的數(shù)據(jù)。

正向信息

按照層次依次保存了從索引到詞的包含關(guān)系:index-->segment-->document-->field-->term。

反向信息

反向信息保存了詞典的倒排表映射:term-->document

配置Lucene開發(fā)環(huán)境

Lucene是ASF的開源項(xiàng)目,最新版本是5.2.1,但是鑒于網(wǎng)絡(luò)上大多數(shù)教程使用的是Lucene 4,在本文中使用的版本是Lucene 4.3.1,下載解壓,到對(duì)應(yīng)目錄找到以下的jar包并添加到構(gòu)建路徑中。

如果使用maven其maven依賴如下:


	org.apache.lucene
	lucene-core
	4.3.1


	org.apache.lucene
	lucene-queryparser
	4.3.1


	org.apache.lucene
	lucene-queries
	4.3.1


	org.apache.lucene
	lucene-highlighter
	4.3.1


	org.apache.lucene
	lucene-analyzers-smartcn
	4.3.1


	org.apache.lucene
	lucene-analyzers-common
	4.3.1
Lucene常用功能介紹 索引創(chuàng)建 創(chuàng)建索的關(guān)鍵類

創(chuàng)建索引的示例代碼:

/**
 * 索引創(chuàng)建
 */
@Test
public void createIndex() {
	
	// 創(chuàng)建一個(gè)分詞器(指定Lucene版本)
	Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_43);	
	// IndexWriter配置信息(指定Lucene版本和分詞器)
	IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_43, analyzer); 
	// 設(shè)置索引的打開方式
	indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
	// 創(chuàng)建Directory對(duì)象和IndexWriter對(duì)象
	Directory directory = null;
	IndexWriter indexWriter = null;
	try {
		directory = FSDirectory.open(new File("Lucene_index/test"));
		
		// 檢查Directory對(duì)象是否處于鎖定狀態(tài)(如果鎖定則進(jìn)行解鎖)
		if (IndexWriter.isLocked(directory)) {
			IndexWriter.unlock(directory);
		}
		
		indexWriter = new IndexWriter(directory, indexWriterConfig);
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	// 創(chuàng)建測(cè)試文檔并為其添加域
	Document doc1 = new Document();
	doc1.add(new StringField("id", "abcde", Store.YES)); 				  // 添加一個(gè)id域,域值為abcde
	doc1.add(new TextField("content", "使用Lucene實(shí)現(xiàn)全文檢索", Store.YES)); // 文本域
	doc1.add(new IntField("num", 1, Store.YES));						  // 添加數(shù)值域
	
	// 將文檔寫入索引
	try {
		indexWriter.addDocument(doc1);
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	Document doc2 = new Document();
	doc2.add(new StringField("id", "yes", Store.YES)); 				 
	doc2.add(new TextField("content", "Docker容器技術(shù)簡(jiǎn)介", Store.YES)); 
	doc2.add(new IntField("num", 2, Store.YES));						 
	try {
		indexWriter.addDocument(doc2);
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	// 將IndexWriter提交
	try {
		indexWriter.commit();
	} catch (IOException e) {
		e.printStackTrace();
	} finally{
		try {
			indexWriter.close();
			directory.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

生成的索引文件如下:

索引檢索 索引檢索關(guān)鍵類

利用以下的檢索程序?qū)η懊鎰?chuàng)建的索引進(jìn)行檢索:

/**
 * 索引檢索
 */
@Test
public void searchIndex(){
	
	Directory directory = null;
	DirectoryReader dReader = null;
	try {
		directory = FSDirectory.open(new File("Lucene_index/test"));	// 索引文件
		dReader = DirectoryReader.open(directory);						// 讀取索引文件
		IndexSearcher searcher = new IndexSearcher(dReader);			// 創(chuàng)建IndexSearcher對(duì)象
		
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_43);    // 指定分詞技術(shù)(標(biāo)準(zhǔn)分詞-與創(chuàng)建索引時(shí)使用的分詞技術(shù)一致)
		
		// 創(chuàng)建查詢字符串(指定搜索域和采用的分詞技術(shù))
		QueryParser parser = new QueryParser(Version.LUCENE_43, "content", analyzer);
		Query query = parser.parse("Docker"); 							// 創(chuàng)建Query對(duì)象(指定搜索詞)
		
		// 檢索索引(指定前10條)
		TopDocs topDocs = searcher.search(query, 10);
		if (topDocs != null) {
			System.out.println("符合條件的文檔總數(shù)為:" + topDocs.totalHits);
			for (int i = 0; i < topDocs.scoreDocs.length; i++) {
				Document doc = searcher.doc(topDocs.scoreDocs[i].doc);
				System.out.println("id = " + doc.get("id") + ",content = " + doc.get("content") + ",num = " + doc.get("num"));
			}
		}
	} catch (IOException e) {
		e.printStackTrace();
	} catch (ParseException e) {
		e.printStackTrace();
	} finally{
		try {
			dReader.close();
			directory.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

運(yùn)行結(jié)果:

Lucene分詞器 常見分詞器

其中IKAnalyzer需要下載專門的jar包

/**
 * 常見分詞器
 */
@Test
public void testAnalyzer(){
	
	final String str = "利用Lucene 實(shí)現(xiàn)全文檢索";
	Analyzer analyzer = null;
	
	analyzer = new StandardAnalyzer(Version.LUCENE_43); 	// 標(biāo)準(zhǔn)分詞
	print(analyzer, str);
	analyzer = new IKAnalyzer();							// 第三方中文分詞
	print(analyzer, str);
	analyzer = new WhitespaceAnalyzer(Version.LUCENE_43); 	// 空格分詞
	print(analyzer, str);
	analyzer = new SimpleAnalyzer(Version.LUCENE_43); 		// 簡(jiǎn)單分詞
	print(analyzer, str);
	analyzer = new CJKAnalyzer(Version.LUCENE_43);			// 二分法分詞
	print(analyzer, str);
	analyzer = new KeywordAnalyzer();						// 關(guān)鍵字分詞
	print(analyzer, str);
	analyzer = new StopAnalyzer(Version.LUCENE_43); 		//被忽略詞分詞器
	print(analyzer, str);

}

/**
 * 該方法用于打印分詞器及其分詞結(jié)果
 * @param analyzer 分詞器
 * @param str 需要分詞的字符串
 */
public void print(Analyzer analyzer,String str){
	
	StringReader stringReader = new StringReader(str);
	try {
		TokenStream tokenStream = analyzer.tokenStream("", stringReader); 			// 分詞
		tokenStream.reset();
		
		CharTermAttribute term = tokenStream.getAttribute(CharTermAttribute.class); // 獲取分詞結(jié)果的CharTermAttribute
		System.out.println("分詞技術(shù):" + analyzer.getClass());
		while (tokenStream.incrementToken()) {
			System.out.print(term.toString() + "|");
		}
		System.out.println();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

運(yùn)行結(jié)果:

Query創(chuàng)建



/**
 * 創(chuàng)建Query
 */
@Test
public void createQuery(){
	
	String key = "JAVA EE Lucene案例開發(fā)";
	String field = "name";
	String[] fields = {"name","content"};
	Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_43); // 分詞器
	
	// 單域查詢
	QueryParser parser1 = new QueryParser(Version.LUCENE_43, field, analyzer);
	Query query1 = null;
	try {
		query1 = parser1.parse(key); // 使用QueryParser創(chuàng)建Query
	} catch (ParseException e) {
		e.printStackTrace();
	}
	System.out.println(QueryParser.class + query1.toString());
	
	// 多域查詢
	MultiFieldQueryParser parser2 = new MultiFieldQueryParser(Version.LUCENE_43, fields, analyzer);
	try {
		query1 = parser2.parse(key);
	} catch (ParseException e) {
		e.printStackTrace();
	}
	System.out.println(QueryParser.class + query1.toString());
	
	// 短語(yǔ)查詢
	query1 = new TermQuery(new Term(field, key));
	System.out.println(TermQuery.class + query1.toString());
	
	// 前綴查詢
	query1 = new PrefixQuery(new Term(field, key));
	System.out.println(PrefixQuery.class + query1.toString());
	
	// 短語(yǔ)查詢
	PhraseQuery query2 = new PhraseQuery();
	query2.setSlop(2); // 設(shè)置短語(yǔ)間的最大距離是2
	query2.add(new Term(field, "Lucene"));
	query2.add(new Term(field, "案例"));
	System.out.println(PhraseQuery.class + query2.toString());
	
	// 通配符查詢
	query1 = new WildcardQuery(new Term(field, "Lucene?"));
	System.out.println(WildcardQuery.class + query1.toString());
	
	// 字符串范圍搜索
	query1 = TermRangeQuery.newStringRange(field, "abc", "azz", false, false);
	System.out.println(TermRangeQuery.class + query1.toString());
	
	// 布爾條件查詢
	BooleanQuery query3 = new BooleanQuery();
	query3.add(new TermQuery(new Term(field, "Lucene")),Occur.SHOULD); // 添加條件
	query3.add(new TermQuery(new Term(field, "案例")),Occur.MUST); 
	query3.add(new TermQuery(new Term(field, "案例")),Occur.MUST_NOT); 
	System.out.println(BooleanQuery.class + query3.toString());
}

運(yùn)行結(jié)果:

IndexSearcher常用方法

檢索關(guān)鍵類

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64432.html

相關(guān)文章

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<