因此,我已经阅读了多个资料,试图解释Solr中的“ docValues”是什么,但是我似乎不明白何时应该使用它们,尤其是在索引字段与存储字段之间。谁能给我一些启示吗?
最佳答案
Solr中的docValue是什么?
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序列化到磁盘一样,我们可以依靠操作系统的文件系统缓存来管理内存,而不是在JVM堆上保留结构。
我什么时候应该使用它们?
由于上述所有原因。
如果您的内存不足,或者不需要为字段建立索引,则DocValues非常适合用于构面/分组/过滤/排序/函数查询。它们还具有增加您可以在不增加内存需求的情况下进行多方面/分组/过滤/排序的字段数的潜力。我一直在生产Solr中使用docvalues进行排序和构面,并且看到这些查询的性能有了极大的提高。