lucene的DocValues不一样于document文档级别的存储,它是一个面向列的存储结构,提供从文档编号到值的映射功能。根据不一样的数据类型和应用场景支持多个DocValuesField类型,SortedDocValuesField即是其中之一,主要的做用是提供字符串值的排序功能(如根据检索条件筛选出结果集后根据某个字符类型的字段进行排序)。算法
先说明一下SortedDocValuesField存储的逻辑结构:.net
给定三个文档doc[0]='abc',doc[1]='abd',doc[2]='abc',值通过排序去重后变成'abc'=0,'abd'=1,那么原始的三篇文档会变成doc[0]=0,doc[1]=1,doc[2]=0。在这样的结构下排序尤为是海量数据时候,无需将原始数据读取到内存中进行排序,只需根据文档的ID号从磁盘中读取排序字段的序号,而后经过优先级队列取前N条记录便可。指针
SortedDocValuesField存储的物理结构主要包含如下几个步骤:blog
一、首先dvd数据文件会写入文档->序号的对应关系,dvm索引文件会记录相应的文件指针(表明dvd文件的XXX-XXX部分记录的是对应关系)排序
二、而后dvd数据文件会写入已去重并排好序的具体的值,因为排好序,所以采用了前缀压缩算法,而且在记录先后缀长度的时候先尽可能用1个字节进行压缩存储(由于在大部分状况下,排序的字段值通常长度都比较小,好比去掉格式符的字符串日期类型仅14位),前缀长度先采用低4位保存超过15后使用vint保存,后缀长度因为最小值为1所以先减去1在左移4位采用高4位进行保存超过16后使用vint保存。为了保证前缀压缩效率lucene是每隔16条记录进行前缀压缩一次,由于记录越靠后公共的前缀越少采用前缀压缩反而增长了占用空间。索引
三、最后写入可以根据词典值随机获取词典序号的索引数据。在写入时lucene按照每1024条记录采用前缀压缩算法,而且只记录前缀值。队列
注意:因为词典值在写入时采用了BytesRefHash,因此值的长度最大只能是32766,详细可参考谈谈lucene中的BytesRefHash。内存