什么是docValues?
docValues是一种记录doc字段值的一种形式,在例如在结果排序和统计Facet查询时,需要通过docid取字段值的场景下是非常高效的。
为什么要使用docValues?
这种形式比老版本中利用fieldCache来实现正排查找更加高效,更加节省内存。倒排索引将字段内存切分成一个term列表,每个term都对应着一个docid列表,这样一种结构使得查询能够非常快速,因为term对应的docid是现成就有的。但是,利用它来做统计,排序,高亮操作的时候需要通过docid来找到,field的值却变得不那么高效了。之前lucene4.0之前会利用fieldCache在实例启动的时候预先将倒排索引的值load到内存中,问题是,如果文档多会导致预加载耗费大量时间,还会占用宝贵的内存资源。
索引在lucene4.0之后引入了新的机制docValues,可以将这个理解为正排索引,是面向列存储的。
DocValues和 field的存储值(field属性设置为stored=“true”)有什么区别?
docValues和document的stored=ture存储的值,都是正排索引,单也是有区别的:
l 存储方式:
DocValues是面向列的存储方式,stored=true是面向行的存储方式,如果通过fieldid取列的值可定是用docValues的存储结构更高效。
l 是否分词:
Stored=true的存储方式是不会分词的,会将字段原值进行保存,而docValues的保存的值会进行分词。
DocValues的实现
docValues的类型:
查了一下lucene的源码,发现DocValues有四种实现方式:
1. Memory
l 实现类:org.apache.lucene.codecs.memory.MemoryDocValuesFormat
运行时正排数据会全部加载到内存中,这部分数据在内存中是压缩存储的
2. Direct
l 实现类:org.apache.lucene.codecs.memory.DirectDocValuesFormat
导入到内存中不压缩使用,这个实际使用的效果应该和老版本的fieldcache差不多吧
3. SimpleText
l 实现类:org.apache.lucene.codecs.simpletext.SimpleTextDocValuesFormat
这个只是当娱乐只用,不用在环境中使用
以上三种类型定义在lucene-codecs-5.3.0.jar的META-INF/services目录下
4. Lucene50(默认使用)
l 实现类:org.apache.lucene.codecs.lucene50.Lucene50DocValuesFormat
Lucene50定义存放在lucene-core-5.3.0.jar的META-INF/services目录下
Lucene50的实现方式和Memory的实现方式大同小异,支持的字段类型更加丰富
在lucene50中将docValues的值分成5种类型:
1. Numeric
2. Binary
3. Sorted
4. SortedSet
5. SortedNumeric
类型是由Schema中的field类型决定的:
l StrField或者UUIDField
如果字段不是多值字段,则类型是SORTED
如果是多值字段,则类型是SORTED_SET
l 数值字段Trie*或者EnumField
如MultiValue=false,则NUMERIC
如MultiValued=true,则SORTED_SET
如何使用
Schema field字段设置
<field name="manu_exact"
type="string" indexed="false" stored="false"
docValues="true" />
另外可以通过fieldtype的docValuesFormat属性来设置docValue的实现策略:
<fieldType name="string_in_mem_dv"
class="solr.StrField" docValues="true"
docValuesFormat="Memory" />
总结
如果在索引上要进行facet,gourp,highlight等查询尽量使用docValue,这样不用为内存开销烦恼了。
例如:solr4.0之后都会需要在schema中设置一个_version_字段来实现对文档的原子操作,为了节省内存,可以加上docValues:
<field name="_version_"
type="long" indexed="true" stored="true" docValues="true"/>