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>