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

时间:2018-01-27 09:44:07

标签: solr lucene

我正在使用

将DocValue添加到文档中
doc.add(new BinaryDocValuesField("foo",new BytesRef("bar")));

要为ID为docId的特定文档检索该值,请调用

DocValues.getBinary(reader,"foo").get(docId).utf8ToString();

BinaryDocValues中的get函数最多支持Lucene 6.6,但对于Lucene 7.0及以上版本,它似乎不再可用。

所以,如何通过Lucene 7 + 中的文档ID获取DocValue(无需迭代BinaryDocValues / DocIdSetIterator,无需重新获取BinaryDocValues并且每次都使用advanceExact

1 个答案:

答案 0 :(得分:4)

理论

Doc值是Lucene的列间跨度值存储。在查询时,为了进行分面和排序,随机访问的Doc值非常快。 以下问题LUCENE-7407将访问模式从随机访问切换到迭代器。因为迭代器API是一种比任意随机访问API更具限制性的访问模式,所以这种变化为Lucene提供了更大的自由度和使用积极压缩和其他优化的能力:

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

您可以在以下博客中了解此更改:

实践

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

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