什么是Solr中的docValues?我应该什么时候使用它们?

gra*_*tii 7 lucene solr

所以,我已阅读,试图解释什么docValues"在Solr的多个来源,但我似乎不明白的时候,我应该使用它们,特别是关系到索引存储VS领域.有人可以请点亮一下吗?

小智 16

什么是Solr中的docValues?

Doc值可以解释为Lucene的列跨步字段值存储,或者仅仅是其未转换的索引或转发索引.

用json来说明:

  • 面向行(存储的字段)

    
    {
    'doc1': {'A':1, 'B':2, 'C':3},
    'doc2': {'A':2, 'B':3, 'C':4},
    'doc3': {'A':4, 'B':3, 'C':2}
    }
    

  • 面向列(docValues)

    
    {
    'A': {'doc1':1, 'doc2':2, 'doc3':4},
    'B': {'doc1':2, 'doc2':3, 'doc3':3},
    'C': {'doc1':3, 'doc2':4, 'doc3':2}
    }
    

DocValues的目的?

存储的字段以行间方式将一个文档的所有字段值存储在一起.在检索中,每个文档一次返回所有字段值,因此加载有关文档的相关信息非常快.

但是,如果您需要扫描一个字段(用于分面/排序/分组/突出显示),这将是一个缓慢的过程,因为您将不得不遍历所有文档并在每次迭代时加载每个文档的字段,从而导致磁盘搜索.

例如,排序,当找到所有匹配的文档时,Lucene需要获取每个文档的字段值.类似地,分面引擎必须查找每个文档中出现的每个术语,这些术语将构成结果集并提取文档ID以构建构面列表.

现在可以通过两种方式解决这个问题:

  • 使用现有的存储字段.在这种情况下,如果您开始在给定字段上进行排序/聚合,数据将被懒惰地反转并在搜索时放入fieldCache,以便您可以访问给定文档ID的值.此过程非常CPU和I/O密集型.
  • DocValues在搜索时访问速度非常快,因为它们以列步长方式存储,因此每次命中只需要解码该一个字段的值.这种方法有望减轻fieldCache的一些内存需求,并且可以更快地查找分面,排序和分组.

就像反向索引docvalues被序列化到磁盘一样,在这种情况下,我们可以依靠OS的文件系统缓存来管理内存而不是保留JVM堆上的结构.

我应该什么时候使用它们?

由于上面讨论的所有原因.如果您处于低内存环境中,或者您不需要索引字段,则DocValues非常适合于分组/分组/过滤/排序/函数查询.它们还有可能在不增加内存需求的情况下增加可以进行分组/分组/过滤/排序的字段数.我一直在生产Solr中使用docvalues进行排序和分面,并且已经看到这些查询的性能有了很大的提高.

  • 当我查看 [SolR 指南](https://lucene.apache.org/solr/guide/8_2/docvalues.html) 时:_Solr 构建索引的标准方式是使用倒排索引。此样式构建在索引中的所有文档中找到的术语列表,每个术语旁边是该术语出现的文档列表(以及该术语在该文档中出现的次数)。_ _DocValue 字段现在是面向列的字段,在索引时构建文档到值的映射。_我对此的理解是,您切换了面向行(=NormalField)和面向列(=DocValues)。正确的? (2认同)

Per*_*ium 6

由于它们的存储和访问方式,它们将加速一些操作,如排序、分面等。

此外,它们对于使用某些功能是强制性的:流表达式、就地更新......

所以,如果有疑问:

  1. 如果您没有大索引,并且大小不是问题,只需启用它们
  2. 如果您确实有一个巨大的索引,或者索引性能很重要,请更仔细地查看它们并选择在哪些字段上启用它们


Pra*_*gam 5

@Persimmonium已经解释了DocValues的用例,并且非常清楚。它们非常适合分面和分类,以及IR世界中许多此类奇特的东西。

什么是docValue,为什么它们在那里? docValue只不过是一种建立前向索引的方式,以便文档指向值。它们的建立是为了克服FieldCache的局限性,它提供了在索引时建立的文档到值的映射,并且它们以基于列的方式存储值,并且在文档索引期间完成了所有繁重的工作。

什么是文档值:

兼容NRT:这些是在索引时构建的按段数据结构,旨在针对数据快速变化的用例有效。

基本查询/过滤器支持:您可以在docvalues字段上进行基本的词,范围等查询,而无需为其建立索引,但是这些查询仅是常数得分,通常速度较慢。如果您关心性能和得分,也可以为该字段编制索引。

比fieldcache更好的压缩: docvalues字段比fieldcache更好的压缩,并且“疯狂”是不可能的。

能够将数据存储在堆内存之外:您可以在fieldType(docValuesFormat =“ Disk”)上指定其他docValuesFormat,以仅在堆上加载最少的数据,而在磁盘上保留其他数据结构。

什么文档值不是:

不能替代存储字段:这些字段在任何方面都与存储字段无关,而是与搜索的数据结构(排序/构面/组/联接/得分)无关。

用例以这种方式与Lucene docValues一起使用。

    public Bits getDocsWithField(FieldInfo field) throws IOException {
  switch(field.getDocValuesType()) {
    case SORTED_SET:
      return DocValues.docsWithValue(getSortedSet(field), maxDoc);
    case SORTED_NUMERIC:
      return DocValues.docsWithValue(getSortedNumeric(field), maxDoc);
    case SORTED:
      return DocValues.docsWithValue(getSorted(field), maxDoc);
    case BINARY:
      BinaryEntry be = binaries.get(field.number);
      return getMissingBits(be.missingOffset);
    case NUMERIC:
      NumericEntry ne = numerics.get(field.number);
      return getMissingBits(ne.missingOffset);
    default:
      throw new AssertionError();
  }
}
Run Code Online (Sandbox Code Playgroud)