lucene

全文检索

全文检索是计算机程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置。当用户查询时根据建立的索引查找,类似于通过字典的检索字表查字的过程。


全文检索(Full-Text Retrieval)是指以文本作为检索对象,找出含有指定词汇的文本。全面、准确和快速是衡量全文检索系统的关键指标。

全文检索特点:
1、只处理文本
2、不处理语义
3、搜索时英文不区分大小写
4、结果列表有相关度排序。

Lucene

一个开源的全文检索框架

lucene相关API介绍

IndexWriter:创建和维护索引库
Analyzer:在创建索引时会用到分词器,在使用字符串搜索时也会用到分词器,这两个地方要使用同一个分词器,否则可能会搜索不出结果。Analyzer(分词器)的作用是把一段文本中的词按规则取出所包含的所有词。对应的是Analyzer类,这是一个抽象类,切分词的具体规则是由子类实现的,所以对于不同的语言(规则),要用不同的分词器。
Directory:索引库的位置
Document:文档是索引和搜索的单元。一个文档可以包含一组Field(字段)
Field:字段,包含名称和值,字段可以选择性的存储在索引中
IndexSearcher:检索工具
Query:查询,lucene中支持模糊查询,语义查询,短语查询,组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。
QueryParser: 是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。
Hits:在搜索完成之后,需要把搜索结果返回并显示给用户,只有这样才算是完成搜索的目的。在lucene中,搜索的结果的集合是用Hits类的实例来表示的。

 

package lucenedemo.lucenedemo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.StringReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;

public class LuceneDemo {

	@Test
	public void buildIndex() throws Exception {

		File path = new File("D:/lucene");
		Directory d = FSDirectory.open(path);

		Analyzer a = new StandardAnalyzer(Version.LUCENE_30);
		// 第一个参数:索引存储的位置
		// 第二个参数:分词器
		// 第三个参数:Filed长度是否受限制
		IndexWriter indexWriter = new IndexWriter(d, a,
				MaxFieldLength.UNLIMITED);
		indexWriter.deleteAll();
		// 构造document
		BufferedReader reader = new BufferedReader(new FileReader(new File(
				"D:/test.txt")));
		String line = null;
		while ((line = reader.readLine()) != null) {
			Document doc = new Document();
			// 如果需要查询则必须设置Index.ANALYZED
			Field field = new Field("line", line, Field.Store.YES,
					Index.ANALYZED);
			doc.add(field);
			indexWriter.addDocument(doc);
		}
		// 优化
		indexWriter.optimize();
		indexWriter.commit();
		indexWriter.close(true);
		reader.close();
	}

	@Test
	public void searchTermQuery() throws Exception {
		File path = new File("D:/lucene");
		Directory d = FSDirectory.open(path);
		IndexSearcher indexSearcher = new IndexSearcher(d);
		Analyzer a = new StandardAnalyzer(Version.LUCENE_30);

		QueryParser queryParser = new QueryParser(Version.LUCENE_30, "line", a);
		Query query = queryParser.parse("Spark");
		// top 5
		TopDocs result = indexSearcher.search(query, 5);
		System.out.println(result.totalHits);
		indexSearcher.close();
	}

	/**
	 * 高亮查询
	 */
	@Test
	public void searchHL() throws Exception {
		File path = new File("D:/lucene");
		Directory d = FSDirectory.open(path);
		IndexSearcher indexSearcher = new IndexSearcher(d);
		Analyzer a = new StandardAnalyzer(Version.LUCENE_30);

		String[] fields = { "line" };
		String[] q = { "spark" };
		Query query = MultiFieldQueryParser.parse(Version.LUCENE_CURRENT, q,
				fields, a);

		TopScoreDocCollector topCollector = TopScoreDocCollector.create(
				indexSearcher.maxDoc(), false);
		
		indexSearcher.search(query, topCollector);
		// 高亮设置
		SimpleHTMLFormatter simpleHtmlFormatter = new SimpleHTMLFormatter(
				"<B>", "</B>");//
		Highlighter highlighter = new Highlighter(simpleHtmlFormatter,
				new QueryScorer(query));

		ScoreDoc[] docs = topCollector.topDocs(5).scoreDocs;
		for (ScoreDoc scdoc : docs) {
			Document document = indexSearcher.doc(scdoc.doc);

			TokenStream tokenStream = a.tokenStream("line", new StringReader(
					document.get("line")));
			String str = highlighter.getBestFragment(tokenStream,
					document.get("line"));
			System.out.println(str);
		}
	}

}

需要的jar包

		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-core</artifactId>
			<version>3.0.0</version>
		</dependency>

		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-analyzers</artifactId>
			<version>3.0.0</version>
		</dependency>

		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-analyzers</artifactId>
			<version>3.0.0</version>
		</dependency>

		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-highlighter</artifactId>
			<version>3.0.0</version>
		</dependency>

		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-memory</artifactId>
			<version>3.0.0</version>
		</dependency>

  

posted @ 2017-05-03 09:39  天之涯0204  阅读(158)  评论(0编辑  收藏  举报