天天看點

no segments* file found in SimpleFSDirectory問題總結

lucene6.0版本

場景一:第一次啟動程式索引庫為空抛出異常

最近在寫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);
            }
        }
    }
}
           

lucene8.2版本

場景一:第一次啟動程式索引庫為空抛出異常

第一次啟動索引庫未空的程式,程式抛出異常代碼如下:

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 如果索引庫存在進行追加,不存在會自動建立

參考部落格:

  1. https://blog.csdn.net/jinwufeiyang/article/details/51817822
  2. https://blog.csdn.net/P397226804/article/details/69396370
  3. http://codepub.cn/2016/06/24/Lucene-6-0-in-action-the-index-of-hot-backup-and-recovery/  (該部落客是阿裡大牛,想學lucene可以看它文章,受益匪淺)