使用 Lucene.Net 的多个应用程序实例

Multiple instances of application using Lucene.Net

我正在开发一个 WPF 应用程序,该应用程序使用 Lucene.Net 从第三方进程生成的文件中索引数据。它的容量很小,每分钟创建的新文件不超过一次。

我的应用程序使用在启动时创建的单例 IndexWriter 实例。类似地,IndexSearcher 也会在启动时创建,但每当 IndexWriter.Commit() 出现时都会重新创建,以确保新添加的文档将出现在搜索结果中。

无论如何,一些用户需要运行 应用程序的两个实例,但问题是在第二个实例中搜索时新添加的文档不会显示出来。我猜这是因为第一个实例正在执行提交,并且需要有一种方法来告诉第二个实例重新创建它的 IndexSearcher。

一种方法是使用文件 create/update 结合 FileSystemWatcher 发出信号,但首先想知道 Lucene.Net 中是否有我可以利用的东西?

我能想到的唯一可能对您有帮助的是IndexReader.Reopen()。这将刷新 IndexReader,但 仅当 自 reader 最初打开后索引已更改。在索引未更新的情况下,它应该会导致最少的磁盘访问,而在索引已更新的情况下,它会尝试仅加载已更改或添加的段。

关于 API 需要注意的一件事:Reopen returns 和 IndexReader。在索引没有变化的情况下,returns同一个实例;否则它 returns 一个新的。原索引reader没有处理掉,需要手动处理:

IndexReader reader = /* ... */;
IndexReader newReader = reader.Reopen();

if(newReader != reader)
{
    // Only close the old reader if we got a new one
    reader.Dispose();
}

reader = newReader;

我现在找不到 .NET 文档,但是 here are the Java docs 用于解释 API.

的 Lucene 3.0.3

如果两个实例都在同一目录中打开了自己的 IndexWriter,那么您将陷入痛苦和间歇性不良行为的世界。

IW 期望并要求对索引目录进行独占控制。这就是锁定文件的原因。

如果第二个实例可以检测到存在一个现有实例,那么您可以只在文件夹上打开一个 IndexReader/Searcher 并在目录更改时重新打开。

但是如果第一个实例关闭会发生什么?索引将不再更新。所以第二个实例需要重新初始化,这次是使用 IW。也许它可以在第一个实例关闭时删除锁定文件时执行此操作。

"better" 方法是启动一个 "service"(只是一个后台进程,可能在系统托盘中)。 所有 个应用程序实例随后将查询该服务。如果应用已启动但未检测到服务,则启动它。