首页 > 解决方案 > Lucene SearcherManager 也许刷新写入索引文件?

问题描述

我正在使用 Lucene 8.5,这就是我现在在我的应用程序中所做的:

  1. 使用IndexWriter.
  2. 调用SearcherManager.maybeRefreshBlocking()SearcherManager使用相同创建IndexWriter)。
  3. 然后 tar 包含文件系统上索引文件的目录。

然后我会收到这样的错误:

tar: ./indexes/_i_Lucene85FieldsIndex-doc_ids_10.tmp: Cannot stat: No such file or directory
tar: Error exit delayed from previous errors.

所以这告诉我在 tar 操作开始时刷新调用还没有完成。我需要一些澄清和帮助:

  1. maybeRefresh()/maybeRefreshBlocking()是异步调用,调用它会修改索引文件吗?
  2. IndexWriter.commit()愚蠢的问题,但是除了commit同步调用之外,还有什么不同之处呢?
  3. 我该怎么做才能确保索引完全“刷新”?换句话说,索引段文件等不再被更新。

我确实尝试将ReferenceManager.RefreshListenerhttps://lucene.apache.org/core/8_5_0/core/org/apache/lucene/search/ReferenceManager.RefreshListener.html)添加到SearcherManager实例并覆盖afterRefresh(boolean),但它似乎在之后被调用尝试而不是实际完成时,因为我仍然遇到上述问题。

      searcherManager.addListener(new ReferenceManager.RefreshListener() {
         @Override
         public void beforeRefresh() {
            refreshing = true;
         }

         @Override
         public void afterRefresh(boolean didRefresh) {
            
            if (didRefresh) {
               refreshing = false;
            }
         }
       });  

任何帮助和建议将不胜感激!

标签: javalucene

解决方案


MaybeRefresh()/maybeRefreshBlocking() 是异步调用,调用它会修改索引文件对吧?

否。这两种方法会刷新与 关联的读取器,SearcherManager如果自当前使用的读取器打开后发生了任何已提交或未提交的写入SearcherManager。这些方法不会将索引更改写入磁盘。
更新:当我说“这些方法现在确实将索引更改写入磁盘”时,我不太正确。确实他们没有提交任何更改,但事实证明他们确实将索引刷新到磁盘,从而创建了一个新的未提交段。

愚蠢的问题,但是除了提交是同步调用之外,还有什么让这个调用与 IndexWriter.commit() 不同?

不是一个愚蠢的问题。commit() 实际上会将任何未提交的写入操作写入磁盘。对索引的写入最初是未提交的,并在内存中缓冲,直到调用 commit()。当调用 commit() 时,这些索引更改将写入新的索引段。

我该怎么做才能确保索引完全“刷新”?换句话说,索引段文件等不再被更新。

调用'IndexWriter.commit()'


推荐阅读