Lucene索引的一个重要特征是支持增量索引。
可以保持原有的索引内容基础上,创建一系列新的子索引。子索引创建完成后,可以自动添加到索引段中,索引段膨胀到一定程度后,又可以自动添加到更大的索引段中。最后可以通过合并和优化生成一个索引文件。
可以说lucene的索引建立过程就是一系列的索引合并过程。
首先利用自动合并功能,合并最小的单元;然后利用addIndexes命令可以把指定的索引合并起来。
另一种重要的操作是 在所有的索引创建完成后,调用优化方法,对IndexWriter指定目录下的所有未合并的索引进行优化。优化合并后的索引具有更好的检索速度。
示例:
/**
* 合并不同索引路径下的索引文件
* @param indexPath 合并目标地址
* @param otherIndexPath
*/
public static boolean indexMerge(File indexPath, File otherIndexPath) {
try {
Analyzer analyzer = new StandardAnalyzer();
IndexWriterConfig conf = new IndexWriterConfig(Version.LATEST, analyzer);
conf.setOpenMode(OpenMode.APPEND);//追加模式添加索引
Directory fsdDir = FSDirectory.open(indexPath);
IndexWriter fsdIndex = new IndexWriter(fsdDir, conf);
Directory ramDir = new RAMDirectory();//内存高速缓冲目录
IndexWriter ramIndex = new IndexWriter(ramDir, conf);//构建内存RAM的内存索引
FSDirectory[] fsDirectories = {FSDirectory.open(otherIndexPath)};
ramIndex.addIndexes(fsDirectories);//添加目录中的索引到内存索引
ramIndex.forceMerge(5);//内存索引优化
ramIndex.close();
fsdIndex.addIndexes(new Directory[] {ramDir});//合并内存索引到目标地址指定的文件索引
fsdIndex.close();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
实际上优化过程就是使用重新创建的索引来存放原来的多个子索引。索引中的文档也会重新编号,最大可能地减少资源浪费。
优化过程需要大量的磁盘和I/O资源,在海量数据的索引和更新过程中,需要注意在何时进行索引的优化,避免优化过程影响其他服务运行。
如果索引用于在线服务,建议采用离线优化和合并索引的方式,然后进行索引服务的切换,比较服务器I/O资源是有限的,在线处理也需要大量的I/O资源来响应客户请求。