如何在 Lucene 7+ 中通过文档 ID 获取 DocValue?

xpa*_*oob 2 lucene solr

我正在向文档中添加一个 DocValue

doc.add(new BinaryDocValuesField("foo",new BytesRef("bar")));
Run Code Online (Sandbox Code Playgroud)

要检索具有 ID 的特定文档的该值docId,我调用

DocValues.getBinary(reader,"foo").get(docId).utf8ToString();
Run Code Online (Sandbox Code Playgroud)

getBinaryDocValues 中的函数最高支持Lucene 6.6,但对于Lucene 7.0及更高版本,它似乎不再可用。

那么,如何在 Lucene 7+ 中通过文档 ID 获取 DocValue(无需迭代BinaryDocValues/ DocIdSetIterator,也无需每次都重新获取BinaryDocValues和使用advanceExact)?

Iva*_*tov 8

理论

Doc 值是 Lucene 的 column-stride 字段值存储。Doc 值旨在为查询时的随机访问速度非常快,以实现分面和排序目的。以下问题LUCENE-7407将访问模式从随机访问切换到迭代器。由于迭代器 API 的访问模式比任意随机访问 API 的限制要多得多,因此此更改为 Lucene 提供了使用积极压缩和其他优化的更多自由和能力:

  • 在数据稀疏的情况下减少磁盘空间使用
  • 更好的压缩率和解码 doc 值的速度,即使在非稀疏情况下
  • 删除缺失值的特殊列(getDocsWithField)和线程本地编解码器阅读器

您可以在以下博客中阅读有关此更改的信息:

实践

实际上,此更改在某些情况下会导致性能下降,例如SOLR-9599。在主要情况下(分面和排序),适当使用迭代 API 是可以的,甚至可以执行一些优化。事实上,在很多情况下,这个 API 并不是一个好的解决方案。所有这些情况都被作为不正确的用法丢弃(我们在 java word 中使用 sun.misc.Unsafe 遇到了同样的问题)。

事实上,org.apache.lucene.index.DocValuesIterator#advanceExact在某些实现的情况下,它非常快并且具有相似的性能和复杂性。