所以,我已阅读,试图解释什么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以构建构面列表.
现在可以通过两种方式解决这个问题:
就像反向索引docvalues被序列化到磁盘一样,在这种情况下,我们可以依靠OS的文件系统缓存来管理内存而不是保留JVM堆上的结构.
我应该什么时候使用它们?
由于上面讨论的所有原因.如果您处于低内存环境中,或者您不需要索引字段,则DocValues非常适合于分组/分组/过滤/排序/函数查询.它们还有可能在不增加内存需求的情况下增加可以进行分组/分组/过滤/排序的字段数.我一直在生产Solr中使用docvalues进行排序和分面,并且已经看到这些查询的性能有了很大的提高.
由于它们的存储和访问方式,它们将加速一些操作,如排序、分面等。
此外,它们对于使用某些功能是强制性的:流表达式、就地更新......
所以,如果有疑问:
@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)