在Lucene4.x之后,出现一个重大的特性,就是索引支持DocValues,DocValues是通过牺牲一定的磁盘空间带来的好处主要有两个(即以空间换时间),该特性有以下两个主要优点:

(1)节省内存 
(2)对排序,分组和一些聚合操作时能够大大提升性能 

下面来详细介绍下DocValue的原理和使用场景 

什么是docValues? 

docValues其实是Lucene在构建索引时,会额外建立一个有序的基于document => field值的映射列表,跟lucene索引相反,lucene索引维护的是doc item => doc ids的映射关系; 

为什么要用docValues? 

      solr是使用经典的倒排索引模式来达到快速检索的目的,简单的说就是建立 搜索词=》 文档id列表 这样的关系映射, 然后在搜索时,通过类似hash算法,来快速定位到一个搜索关键词,然后读取其的文档id集合,这就是倒排索引的核心思想,这样搜索数据是非常高效快速的。

      当然它也是有缺陷的,假如我们需要对数据做一些聚合操作,比如排序,分组时,lucene内部会遍历提取所有出现在文档集合的排序字段然后再次构建一个最终的排好序的文档集合list,这个步骤的过程全部维持在内存中操作,而且如果排序数据量巨大的话,非常容易就造成solr内存溢出和性能缓慢。 
      基于这个原因,在lucene4.x之后出现了docvalue这个新特性,在构建索引时会对开启docvalues的字段,额外构建一个已经排好序的文档到字段级别的一个列式存储映射,它减轻了在排序和分组时,对内存的依赖,而且大大提升了这个过程的性能,代价就是耗费一定的磁盘空间。 

什么时候应该用docValues? 

通过上面的剖析,散仙相信大家已经对DocValues有一个初步的了解了,至于它的应用场景,那么也非常明显了,总结起来主要以下几个方面: 

1,需要聚合的字段,包括sort,agg,group,facet等 
2,需要提供函数查询的字段 
3,需要高亮的字段
4,需要参与自定义评分的字段 

docValues特性支持的字段类型: 

A: 字符串或UUID字段+单值 会选择SORTED作为docvalue存储 
B: 字符串或UUID字段+多值 会选择SORTED_SET作为docvalue存储 
C:数值或日期或枚举字段+单值 会选择NUMERIC 作为docvalue存储 
D:数值或日期或枚举字段+多值 会选择SORTED_SET作为docvalue存储 

注:

1.修改schema.xml中字段的docValues属性后需要在更新完solr config后重新更新索引才能生效

2.设置为docValues="true"的字段默认是意味着该字段保存了,useDocValuesAsStored默认为true,如果useDocValuesAsStored设置为false,如果想要在查询时继续返回该字段,需要使用fl明确选择该字段,fl:*不能返回useDocValuesAsStored的docValues字段

3.doValues字段如果stored="false"时,如果该字段是多值字段,那么查询返回的值为排序后的字段,不一定跟插入时顺序一致