Lucene.NET 不是删除文档吗?

Lucene.NET is not deleting docs?

我可能经历过无数次 S.O。关于这个问题的帖子,但我很茫然,无法弄清楚问题是什么。

我可以在索引中添加和更新文档,但我似乎无法成功删除它们。

我正在使用 Lucene.NET v3.0.3

我读到一个建议是使用相同条件执行 查询 并确保我得到返回结果。好吧,我这样做了:

首先,我有一个方法可以将数据库中 returns 项标记为已删除

var deletedItems = VehicleController.GetDeleted(DateTime lastcheck);

目前在测试期间,这包括一个项目。然后我迭代:

// This method returns my writer
var indexWriter = LuceneController.GetWriter();

// And my searcher
var searcher = new IndexSearcher(indexWriter.GetReader());

// And iterate over my items (just one for testing)
foreach(var c in deletedItems) {

  // Here I'm testing by doing a query
  var query = new BooleanQuery();
  query.Add(new TermQuery(new Term("key", c.Guid.ToString())), Occur.MUST);

  // Let's see if it can find the record based on this
  var docs = searcher.Search(query, 1);

  var foundDoc = docs.FirstOrDefault();

  // Yep, we have one... let's get the full doc to be sure
  var actualDoc = searcher.Doc(foundDoc.Doc);

  // If I inspect actualDoc, it's the right one... I want to delete it.
  indexWriter.DeleteDocuments(query);
  indexWriter.Commit();

}

为了更容易阅读,我试图把上面的逻辑全部打碎,但是我尝试了各种方法...

indexWriter.Optimize();
indexWriter.Flush(true, true, true);

如果我查看存储所有内容的实际文件夹,我可以看到 0_1.del 之类的文件名和弹出窗口之类的内容,这看起来很有希望。

然后我在某处阅读了有关合并策略的信息,但这不是 Flush 应该做的吗?

然后阅读以尝试将优化方法设置为最大 1,但仍然无效(即 indexWriter.Optimize(1))。

因此,使用相同的查询来获取有效,但删除无效。为什么?我还能检查什么?删除实际上是永久删除该项目还是以其他方式继续存在,直到我完全删除正在使用的目录?没看懂。

Lucene 中的索引段文件是不可变的,一旦写入就永远不会改变。因此,当记录删除时,删除的记录实际上并没有立即从索引文件中删除,只是将记录标记为已删除。一旦合并该索引段以生成新段,该记录最终将从索引中删除。即删除的记录不会在合并结果的新段中。

理论上,一旦 commit 被调用,删除应该从 reader 的视图中删除,因为您从作者那里得到 reader(即它是实时 reader) 这在此处记录:

Note that flushing just moves the internal buffered state in IndexWriter into the index, but these changes are not visible to IndexReader until either commit() or close() is called.

来源:https://lucene.apache.org/core/3_0_3/api/core/org/apache/lucene/index/IndexWriter.html

但您可能想在删除发生后尝试关闭 reader,然后从作者那里获取新的 reader,看看新的 reader 现在是否有记录从可见性中移除。