最近在写lucene发现利用lucene6.0版本时候如果索引库为空构建indexWriter,代码如下:
IndexWrterConfig config = new IndexWriterConfig(analyzer);
IndexWriter indexWriter = new IndexWriter(config);
IndexReader reader = IndexReader.open(directory);
程序顺序执行上面代码块是正常的,但是调用iIndexReader reader = IndexReader.open(directory); 后报错“no segments* file”。
解决办法:在获取indexWriter对象后手动commit一次建立索引库版本信息,最终问题解决!代码如下:
IndexWrterConfig config = new IndexWriterConfig(analyzer);
IndexWriter indexWriter = new IndexWriter(config);
indexWriter.commit();//手动提交一次
IndexReader reader = IndexReader.open(directory);
异常原因:可能是文件读写异常终止以后,程序再次启动时候,lucene对索引库进行合并读取操作,信息缺失,索引库读取和合并操作失败。
解决办法:在indexWriter.commit()后没有调用indexWriter.close()方法,此时文档内容为空
解决办法:可以用如下代码修复索引,会帮你删除损坏的索引文件
/**
* @param source 索引源
* @param dest 索引目标
* @param indexWriterConfig 配置相关
*/
public static void recoveryIndex(String source, String dest, IndexWriterConfig indexWriterConfig) {
IndexWriter indexWriter = null;
try {
indexWriter = new IndexWriter(FSDirectory.open(Paths.get(dest)), indexWriterConfig);
} catch (IOException e) {
log.error("", e);
} finally {
//说明IndexWriter正常打开了,无需恢复
if (indexWriter != null && indexWriter.isOpen()) {
try {
indexWriter.close();
} catch (IOException e) {
log.error("", e);
}
} else {
//说明IndexWriter已经无法打开,使用备份恢复索引
//此处简单操作,先清空损坏的索引文件目录,如果索引特别大,可以比对每个文件,不必全部删除 try {
FileUtils.deleteDirectory(new File(dest));
FileUtils.copyDirectory(new File(source), new File(dest));
} catch(IOException e){
log.error("", e);
//使用备份恢复出错,那么就使用最后一招修复索引
log.info("Check index {} now!", dest);
try {
IndexUtils.checkIndex(dest);
} catch (IOException | InterruptedException e1) {
log.error("Check index error!", e1);
}
}
}
}
第一次启动索引库未空的程序,程序抛出异常代码如下:
IndexWriterConfig writerConfig = new IndexWriterConfig(analyzer);
IndexWriter indexWriter = new IndexWriter(dic,writerConfig);
解决方法:直接在IndexWriterConfig参数中配置索引库不存在时候创建即可,代码如下:
IndexWriterConfig writerConfig = new IndexWriterConfig(analyzer);
writerConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);//解决
IndexWriter indexWriter = new IndexWriter(dic,writerConfig);
IndexReader reader = DirectoryReader.open(dic);
说明:查询了http://lucene.apache.org/core/8_2_0/core/index.html文档,发现OpenMode有以下三个参数:
APPEND | 索引库版本信息(索引库是否为空)存在则追加操作 |
CREATE | 不管索引版本信息是否存在重新创建索引库 |
CREATE_OR_APPEND | 如果索引库存在进行追加,不存在会自动创建 |
参考博客: