Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。
Lucene的实现机制是倒排表。例如现在有2个文档需要建立索引,内容分别为"Lucene Learning"和"Lucene Hadoop",建立后的索引实际是这样的:
索引的优势在于:虽然建立索引会比较耗时,但是在一次建立后便可以永远支持高效的查询。
Lucene的核心类有:
Directory:索引对象,常用有RAMDirectory和FSDirectory两种,前者代表一个内存中的索引文件,后者代表一个本地的索引文件。
Filed:字段,由name和value组成,常用的字段分为三种:
Document:索引中存储的文档结构,一个文档由多个字段组成。
Term:词元,相当于索引中的键,每个Term都指向一个由文档组成的链表。
IndexReader:索引的读取流,可以从索引中读取出需要的文档。
IndexWriter:索引的输出流,将文档写入索引。
IndexSearcher:索引的搜索功能。
Query:搜索条件。
Analyzer:分词器,可以将字段中的数据分解成多个词元。
Lucene的流程:
写入:将数据源转换为文档,然后使用IndexWriter的addDocument方法将文档添加到索引。
查询:使用IndexReader获取一个IndexSearcher对象,并创建一个Query对象指定查询类型,然后使用IndexSearcher的search方法得到文档。
代码实例:
添加索引:
public static void init() throws IOException {
//索引文件
Directory dir = FSDirectory.open(new File("E:/index"));
//索引配置(指定Lucene版本和分词器)
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_0, new StandardAnalyzer());
//得到输出流
IndexWriter writer = new IndexWriter(dir, config);
//创建文档
Document doc = new Document();
//id会以一个整体被作为词元被索引 并且会被存储在文档中
doc.add(new StringField("id", "123", Field.Store.YES));
//content会被分词器分割成数个词元被索引 但不会存储在文档中
doc.add(new TextField("content", "Lucene是apache软件基金会4 jakarta" +
"项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎," +
"而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎," +
"部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件" +
"开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的" +
"功能,或者是以此为基础建立起完整的全文检索引擎。", Field.Store.NO));
//address会被分词器分割成数个词元被索引 并且会存储在文档中
doc.add(new TextField("address", "北京市海淀区翠微路凯德大厦", Field.Store.YES));
//将文档添加到索引
writer.addDocument(doc);
//打印当前已经被索引的文档个数
System.out.println("被索引的文档个数:" + writer.numDocs());
writer.close();
}
遍历索引中所有的文档:
public static void ergodic() throws IOException {
//索引文件
Directory dir = FSDirectory.open(new File("E:/index"));
//得到输入流
IndexReader reader = DirectoryReader.open(dir);
IndexSearcher searcher = new IndexSearcher(reader);
Document doc = null;
for (int i = 0; i < reader.maxDoc(); i++) {
doc = searcher.doc(i);
System.out.println("Doc [" + i + "] : id: "
+ doc.get("id") + ", desc: " + doc.get("content"));
}
}
public static void search() throws IOException, ParseException {
//索引文件
Directory dir = FSDirectory.open(new File("E:/index.txt"));
//输入流
IndexReader reader = DirectoryReader.open(dir);
IndexSearcher searcher = new IndexSearcher(reader);
// 搜索条件
QueryParser parser = new QueryParser("desc",
new StandardAnalyzer());
Query query = parser.parse("索引文件");
// 搜索结果
TopDocs hits = searcher.search(query, 2);
System.out.println("查询出来的总数是:" + hits.totalHits);
// 获取搜索结果
Document doc = null;
for (ScoreDoc scoreDoc : hits.scoreDocs) {
doc = searcher.doc(scoreDoc.doc);
System.out.println("Doc [" + scoreDoc.doc + "] : id: "
+ doc.get("id") + ", desc: " + doc.get("content"));
}
}