Lucene近实时搜索

3

我正在使用Lucene 6.6.0,并且希望使用Lucene的近实时搜索功能。但是,我无法成功实现它。我尝试获取该功能的方式如下:

我初始化了一个IndexReader实例:

this.reader = DirectoryReader.open(this.directory);

假设通过IndexWriter实例对索引进行了一些更改。然后,如果我理解正确,我需要第二个IndexReader实例来提交更新:
this.newReader = DirectoryReader.openIfChanged(this.reader);
if (this.newReader != null) {
    // Update the IndexSearcher with the new IndexReader instance
    this.searcher = new IndexSearcher(this.newReader);
    this.reader.close();
}

问题在于代码无法编译,因为出现了以下错误:The method openIfChanged(DirectoryReader) in the type DirectoryReader is not applicable for the arguments (IndexReader)
那么我该如何更新IndexReader呢?
其次,如果我再次更新索引,我需要另一个IndexReader实例,对吗?在程序执行期间自由更新索引的最佳方法是在每次更新后在两个IndexReader实例之间切换吗?
谢谢。
1个回答

4
尝试使用SearcherManager替代IndexReader: http://lucene.apache.org/core/6_6_0/core/org/apache/lucene/search/SearcherManager.html 使用SearcherManager,您可以执行以下方法:
// get a IndexSearcher for searching
IndexSearcher searcher = searcherManager.aquire();

// release IndexSearcher after search
searcherManager.release(searcher);

// refresh and add new index records to next search. usually after a commit 
searcherManager.maybeRefresh();

我也尝试实现了这个,基本上做了以下几步:
  • 创建一个IndexWriter并保持其打开状态
  • 使用IndexWriter作为参数创建一个SearcherManager
  • 使用SearcherManager进行搜索
  • 使用IndexWriter进行索引操作
  • 在索引完成后进行提交
此外,您可以使用单独的线程定期提交而不是在每次写入时提交,因为提交操作可能会非常"昂贵"。
示例请参见: http://www.lucenetutorial.com/lucene-nrt-hello-world.html

我按照你说的做了,看起来运行得很好。当发生一些变化时,我调用以下代码:this.writer.maybeMerge(); this.writer.commit(); this.searcherManager.maybeRefresh();这三行代码是为了能够在更新后的索引中进行搜索,对吗?我更喜欢在索引之后手动调用这些方法来刷新索引,而不是使用线程,因为在我的情况下,索引只在开始时进行,所以没有必要定期刷新它。当索引是动态的时候,使用线程来刷新索引会更优,对吗? - C. Güzelhan
提交(commit)和可能刷新(maybeRefresh)是必要的,是的。不确定是否真的需要maybeMerge,但你必须检查一下。 嗯,等一下,如果你只索引一次,为什么要实现NRT(Near Real-Time)用例呢?在初始索引之后,你没有对索引进行任何更改吗? - dom
从技术上讲,不是的,但我只索引属于特定文件类型的文档。当我执行程序时,新的文件类型也可以被索引,我不想从头开始构建索引,而是用新的文档更新现有的索引。我还希望在初始更新之后能够随时更新索引,以防将来可能需要它。 - C. Güzelhan
好的,这样做没问题。在这种情况下,使用NRT(Near Real-Time)实现是有用的。根据你的问题:如果在很短的时间间隔内有很多变化,那么专用线程是有意义的。在这种情况下,执行提交操作可能会锁定其他线程,因为它们必须等待提交完成。所以在这种情况下,有一个专用线程每隔5秒钟进行一次提交是有意义的。 - dom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接