Lucene.. NET在更新文档后的查询中返回错误的文档



搜索正常工作,直到我更新索引中的文档。在搜索中不再返回已更新的文档,而是返回一个完全不相关的文档,且docId=0。

我是这样设置的:

var luceneVersion = LuceneVersion.LUCENE_48;
var analyzersPerField = new Dictionary<string, Analyzer>
{
["name"] = new KeywordAnalyzer()
};
var __analyzer = new PerFieldAnalyzerWrapper(new StandardAnalyzer(luceneVersion), analyzersPerField);
var __luceneDirectory = FSDirectory.Open(_searchDirectory);
var indexConfig = new IndexWriterConfig(luceneVersion, __analyzer)
{
OpenMode = OpenMode.CREATE_OR_APPEND,
};
var _writer = new IndexWriter(__luceneDirectory, indexConfig);
var __directoryReader = DirectoryReader.Open(__luceneDirectory);
var _searcher = new IndexSearcher(__directoryReader);
var _queryParser = new StandardQueryParser(__analyzer);

文档是这样定义的:

private static Document CreateDocument(FileResult fileResult)
{
var document = new Document
{
new StringField("id", fileResult.Id, Field.Store.YES)
};
document.Add(new TextField("baseKeywords", fileResult.AlternativeName, Field.Store.NO));
document.Add(new StringField("name", fileResult.AlternativeName, Field.Store.YES));
return document;
}

下面是文档的更新方式:

public void UpdateDocumentName(FileResult fileResult, string newName)
{
fileResult.AlternativeName = newName;
var document = CreateDocument(fileResult);
_writer.UpdateDocument(new Term("id", fileResult.Id), document);
}

更新完成后,我做一个提交并创建新的reader:

_writer.Commit();
__directoryReader = DirectoryReader.OpenIfChanged(__directoryReader) ?? __directoryReader;
_searcher = new IndexSearcher(__directoryReader);

如何搜索文档:

_queryString = QueryParserUtil.Escape(searchParameters.QueryString);
var query = _queryParser.Parse(searchParameters.QueryString, "baseKeywords");
_searcher.Search(query, resultsCollector.GetCollector());

自定义收集器定义为:

private List<(int doc, float score)> _results;
public ICollector GetCollector()
{
return Collector.NewAnonymous(setScorer: (scorer) =>
{
_scorer = scorer;
}, collect: (doc) =>
{
_results.Add((doc, _scorer.GetScore()));
}, setNextReader: (context) =>
{
//
}, acceptsDocsOutOfOrder: () =>
{
return true;
});
}

这些是完整源代码的摘录,可在此处获得

这种行为是一致的,即使在对只返回更新文档的不同字段使用查询时,我得到docId=0。如果我在Luke中打开索引,则不存在此行为,并且我能够查询更新的文档。

我正在更新的文档有最高的文档编号,所以也许我认为这是一个问题?

我尝试更新一个不同的文档,现在我无论何时查询,我得到docId=0。

如果我查询docId=0的文档,我得到的是docId=0的文档,而不是更新后的文档。

我最初使用的是_writer.GetReader(applyAllDeletes: true);的阅读器,但切换到DirectoryReader.Open没有改变任何东西。

也许这是某种我不知道的默认返回值?不知道为什么它总是返回docId=0。

自定义收集器设置错误!

来自Lucene。网络文档:

注意:传递给collect方法的文档是相对于当前阅读器的。如果你的收集器需要将其解析为Multi*Reader的docID空间,你必须通过记录最近SetNextReader(AtomicReaderContext)调用的docBase来重新定义它。

下面是固定收集器:

private List<(int doc, float score)> _results;
private int docBase;
public ICollector GetCollector()
{
return Collector.NewAnonymous(setScorer: (scorer) =>
{
_scorer = scorer;
}, collect: (doc) =>
{
_results.Add((doc + docBase, _scorer.GetScore()));
}, setNextReader: (context) =>
{
docBase = context.DocBase;
}, acceptsDocsOutOfOrder: () =>
{
return true;
});
}

最新更新