1. Lucene简介
Lucene是一个apache的用于全文检索的开源框架, 现在有多种语言版本, 本人主要学习的是java版本的.
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎. (摘自百度百科: http://baike.baidu.com/view/371811.htm?fr=aladdin)
截止到现在, Lucene最新版本已经到了4.9.0. Lucene的索引建立的时候,是以二进制形式写入文件的, Luke是一个开源的查看Lucene索引的工具, 非常方便.
Lucene官网地址: http://lucene.apache.org/
Luke下载地址: https://github.com/DmitryKey/luke/releases
2. Lucene基本使用
在使用Lucene进行全文检索的时候, 主要分两步, 首先是建索引, 然后进行检索.Lucene使用的是倒排索引, 即把待检索的文件分解成一个一个的Token,形成Token流, 然后在Token后面附带上一系列的信息, 写入文件中. 这些内容以一种 精心设计 过的数据形式存放起来, 供检索的时候使用, 由于经过精心设计, 所以检索起来的效率 相比于 直接从数据库中进行检索 要快上非常多.
在建索引的过程中, 需要使用的类: Directory, Analyzer, IndexWriter, Document, Field
Directory代表的是索引文件所在的目录, 可以硬盘文件(FSDirectory), 也可以是在内存(RAMDictory)中.
Analyzer就是分词器, 分词器接收待检索的文件, 并把待检索的文件分解成一个一个的Token, 形成一个Token流, 一般默认的分词器使用的是StandardAnalyzer. Lucene的分词器对英文的支持会比较好, 对中文的支持不是太好, 需要自己实现分词.
IndexWriter, 顾名思议, 是将写索引文件的类. 根据索引文件存放的地方不同, 可能写入文件中或者内存中.
Document, 代表的是一个 建立索引 和 检索的 基本单元, 一个Document是多个Field的集合, 每个Field都是一个key/value对.
FSDirectory dir = FSDirectory.open(new File(index_path));
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_47);
IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_47, analyzer);
IndexWriter writer = null;
File test_files[] = null;
test_files = new File("D:\\lucene\\example\\test_files").listFiles();
for(File f : test_files){
Document doc = new Document();
doc.add(new StringField("path",f.getAbsolutePath(),Field.Store.YES));
doc.add(new TextField("content", FileUtils.readFileToString(f), Field.Store.YES));
doc.add(new StringField("last_modified", Long.toString(f.lastModified()), Field.Store.YES) );
writer.addDocument(doc);
}
writer.close();
System.out.println("index ok!");
return ;
在检索的过程中, 使用到的类: IndexReader, IndexSearcher, Query, TopDocs, ScoreDoc
IndexReader, 与IndexWriter相对应, 是从索引文件存放的位置读索引的类, 是一个抽象类, 具体的子类实例可以通过 DirectoryReader.open()方法获取.
IndexSearcher, 进行检索的类,持有一个IndexReader对象, 应用程序可以调用IndexSearcher.search()方法
进行检索.
Query代表查询的条件, IndexSearcher进行检索的时候, 会根据Query设置的各种条件去进行检索. Query有很多子类, 常用的有TermQuery, BooleanQuery,PhraseQuery等.
TopDocs代表检索命中的集合,由IndexSearcher.search()方法返回.
ScoreDoc代表命中集合中的一个document, ScoreDoc持有Document的number, 可以通过这个number去获取到具体的Document.
IndexReader reader = DirectoryReader.open(FSDirectory.open(new File(index_path)));
//1,创建IndexSearcher
IndexSearcher searcher = new IndexSearcher(reader);
//2,创建Query
Query query = new TermQuery(new Term("content", "key"));
//3,创建TopDocs
TopDocs docs = null;
docs = searcher.search(query, 10);
//4,获取ScoreDoc[]
ScoreDoc[] scoreDoc = docs.scoreDocs;
//5,打印结果
System.out.println(scoreDoc.length + "<--scoreDoc.length ");
System.out.println(docs.totalHits + "<--TopDocs.totalHits");
for(ScoreDoc doc :scoreDoc){
Document document = searcher.doc(doc.doc);
System.out.println("score doc number is " + doc.doc);
System.out.println("score doc score is " + doc.score);
System.out.println("score doc string is " + doc.toString());
}