Lucene系列:番外篇-DocValues
玩ElasticSearch或Solr的童鞋,对于DocValues这个词,时常出现高阶应用开发者的口中。它像一个熟悉的陌生人一样,很多人对于实现排序,分组和一些聚合类操作的需求信手拈来,但对它底层原理却了解不多。
DocValues在LUCENE-3518才引入新特征,初生在Lucene4.0,由Mike(Michael McCandless)提出的。从此Lucene牛逼轰轰了。
1. 为什么要用DocValues ?
假如我们需要对一些数据做一些聚合操作,比如排序,分组该如何实现呢?
基于lucene的solr和es都是使用经典的倒排索引模式来达到快速检索的目的,简单的说就是建立 搜索词=》 文档id列表 这样的关系映射, 然后在搜索时,通过类似hash算法,来快速定位到一个搜索关键词,然后读取其的文档id集合,这就是倒排索引的核心思想,这样搜索数据是非常高效快速的。当然它也是有缺陷的,要实现上面的需求,lucene内部会遍历提取所有出现在文档集合
的排序字段然后再次构建一个最终的排好序的文档集合list,这个步骤的过程全部维持在内存中操作,而且如果排序数据量巨大的话,非常容易就造成ES内存溢出和性能缓慢。
基于这个原因,在lucene4.x之后出现了docvalue这个新特性,在构建索引时会对开启docvalues的字段,在构建索引时会对开启docvalues的字段,额外构建一个已经排好序的文档到字段级别的一个列式存储映射。它带来的好处是:
- 节省内存
- 对排序,分组和一些聚合操作时能够大大提升性能
2. 什么时候用DocValues?
通过上面的剖析,总结起来主要以下几个方面:
- 需要聚合的字段,包括sort,agg,group,facet等
- 需要提供函数查询的字段
- 需要高亮的字段,这个确实能加速,但是散仙并不建议把高亮放在服务端程序做
- 需要参与自定义评分的字段,这个稍复杂,大多数人的场景中,不一定能用到
3. DocValues存储结构
DocValues字段是一个面向列存储的字段,所谓面向列存储,相信大家都不会陌生了,市场上也有好多成熟的列存储框架诸如:Parquet、ORC等。
- 一个Segment只有一个DocValues
- 被DocValues标记的字段在建索引时会额外存储文件到值的映射关系
- 一个DocValues会生成两个文件(dvd,dvm)。dvd,存储这个映射的文件叫DocValues data。dvm,对应的元数据文件叫DocValues Metadata,这里metadata相当于Index文件,用来存储数据的索引,也就是存储数据文件每条记录起始位置以及记录的长度,同时存储数据文件的数据格式等信息(即是元信息)
- 所有
Doc Values
存于内存中(堆外内存),这样就可以有超快的访问速度
Doc values通过逆置term和doc间的关系来前面提到的数据聚合的问题。当数据被逆置之后,想要收集到 Doc_1 和 Doc_2 的唯一 token 会非常容易。获得每个文档行,获取所有的词项,然后求两个集合的并集。
Doc Terms
-----------------------------------------------------------------
Doc_1 | brown, dog, fox, jumped, lazy, over, quick, the
Doc_2 | brown, dogs, foxes, in, lazy, leap, over, quick, summer
Doc_3 | dog, dogs, fox, jumped, over, quick, the
-----------------------------------------------------------------
它也不是实时(同index一样),Writer只负责把DocValues字段按对应DocValues类型写入到内存上,最后在Segment refresh的时候,由Consumer把Writer的内容写入磁盘。
4. DocValues的种类
Lucene提供这五种类型的Writer(DocValues类型),它适配情况是这样的
NONE | 不开启docvalue时的状态 | |
Numeric | NumericDocValuesWriter | 对于一般的integer/long/float/double/date |
Binary | BinayDocValuesWriter | 对应BinaryField,并且它会被转成byte[]进行存储 |
Sorted | SortedDocValuesWriter | 对应String |
Sorted Set | SortedSetDocValuesWriter |
对应StrField字段,但仅限于multiValue="true" 的情况
|
Sorted Number | SortedNumericDocValuesWriter | 对应所有Trie*Field,包括TrieIntField和TrieDateField |
注意:analyzed String字段存储docvalue是没有意义的(因为分词后会生成很多token使得Doc Values
效率降低),因此docValues不支持TextField类型
5. docValuesFormat
docValues提供了四种Format,你可能会认为MemoryDocValuesFormat只会存储在内存,而不存储在磁盘,其实真不是这样的。不管是DirectDocValuesFormat还是MemoryDocValuesFormat都会存盘,后缀名分别为.dvdd
和.dvdm
以及.mdvd
和.mdvm
。
- Lucene54DocValuesFormat,默认的Format,存储在磁盘。跟FieldCache比较像,需要时如果没有就去磁盘里读取,不用时也能释放
- MemoryDocValuesFormat,它绝对不是如名那些In-Memory,它其实还比较复杂。应该说,它允许你只读一定大小的DocValues驻在内存。同时它支持以FST的格式存储。
- DirectDocValuesFormat,这个关系是Direct,直接。直接存储到磁盘;直接读取出来放在内存。以一个非常简单的结构存储在内存中——数组。它跟MemoryDocValuesFormat最大的一样就是它支持1或0,要么都存;要么都不存
- SimpleText,Lucene4.0的试验产品
6. 如何使用
//数值存储例子
FieldType num=new FieldType();
num.setStored(true);//设置存储
num.setIndexOptions(IndexOptions.DOCS);//设置索引类型
num.setNumericType(NumericType.DOUBLE);//数值类型
num.setDocValuesType(DocValuesType.NUMERIC);//DocValue类型
Document doc=new Document();
//添加string字段
doc.add(new SortedDocValuesField("id",new BytesRef("01011")));
//添加数值类型的字段 Float,Doule需要额外转成bit位才能存储,Interger和Long则不需要
doc.add(new DoubleField("price", Double.doubleToRawLongBits(25.258), num)); //读取索引文件
DirectoryReader reader=DirectoryReader.open(FSDirectory.open(Paths.get(indexDir)));
//如果有多个段需要merge成一个,获取第一个进行测试,本例中仅仅就有一个段
SortedDocValues str = DocValues.getSorted(reader.leaves().get(0).reader(), "id");
//数值类型
NumericDocValues db = DocValues.getNumeric(reader.leaves().get(0).reader(), "price");
//读取字符串类型的ByteRef然后打印其内容
System.out.println("id:"+str.get(0).utf8ToString());
//注意此处,要与类型对应,如果是Float,则需要Float.intBitsToFloat((int)db.get(0))进行位数还原
System.out.println("price: "+Double.longBitsToDouble(db.get(0)));
reader.close();
在Solr中docvalue默认是全部关闭,比较严谨,大家可酌情开启。在ElasticSearch中,默认docvalue全部激活,比较简单暴力,大家可酌情关闭一些不需要使用docvalue的字段,以节省磁盘空间 。
Lucene系列:番外篇-DocValues相关推荐
- 骨龄预测系列---番外篇
索引 前言 一.DataGenerator是什么? 二.使用步骤 总结 前言 在跑这个系列的代码的时候,发现数据太大了,9G呢~~~,所以引入数据生成器来减轻一下负担 一.DataGenerator是 ...
- 【功能安全(ISO 26262)系列】番外篇 第一话 戏说汽车安全是个什么鬼
更多汽车专业精彩内容尽在微信公众号: AUTO世代 写在前面的话 最近开了个汽车功能安全专题系列: 功能安全(ISO 26262)系列 主要阐述汽车功能安全(ISO 26262)关键专业内容及个人学习 ...
- python爬虫进程和线程_python爬虫番外篇(一)进程,线程的初步了解-阿里云开发者社区...
整理这番外篇的原因是希望能够让爬虫的朋友更加理解这块内容,因为爬虫爬取数据可能很简单,但是如何高效持久的爬,利用进程,线程,以及异步IO,其实很多人和我一样,故整理此系列番外篇 一.进程 程序并不能单 ...
- [zt]数学之美番外篇:平凡而又神奇的贝叶斯方法
数学之美番外篇:平凡而又神奇的贝叶斯方法 Tags: 数学, 机器学习与人工智能, 计算机科学 save it69 saved tags: 贝叶斯 math bayesian algorithm 数学 ...
- 转:数学之美番外篇:平凡而又神奇的贝叶斯方法 收藏
为什么80%的码农都做不了架构师?>>> 转自:http://blog.csdn.net/pongba/archive/2008/09/21/2958094.aspx 数学之美 ...
- Java微信公众平台开发--番外篇,对GlobalConstants文件的补充
转自:http://www.cuiyongzhi.com/post/63.html 之前发过一个[微信开发]系列性的文章,也引来了不少朋友观看和点评交流,可能我在写文章时有所疏忽,对部分文件给出的不是 ...
- 【转】动态模型及其求解介绍–番外篇
上一篇文章(中篇)里 面,我用的示意图是因子图,而里面也出现了Psi函数,本来应该当时就解释清楚的,但实在没有精力写那么多东西,所以就想放到下篇讲的.后来发现,讲条件 随机场要结合有向无向图和inde ...
- 你所能用到的数据结构之番外篇---逆袭的面向对象(一)
对于番外篇,我深刻能明白在大多数人眼里就和电视剧的广告一样,说实话,我也不喜欢这种感觉,因为这样会让人觉得是在欺骗消费者啊~~~阿西巴~~~但是我实在发现如果不在这里对面向对象来个入门级的介绍,后面的 ...
- 【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...
- Python-Matplotlib可视化(番外篇)——Matplotlib中的事件处理详解与实战
Python-Matplotlib可视化(番外篇)--Matplotlib中的事件处理详解与实战 前言 事件连接 事件属性 实战1:直方图中矩形的拖拽 实战2:鼠标进入和离开 相关链接与参考 前言 在 ...
最新文章
- 1.4 微生物对人类社会的影响
- 什么样的人不适合做SEO呢
- Mybatis的insert方法
- ubuntu docker用mount或volume与windows共享文件(samba)(设置共享ip地址)
- MongoDB 性能瓶颈分析
- Rustup 管理工具
- C#读取Excel表格数据到DataGridView中和导出DataGridView中的数据到Excel
- mysql添加新用户
- Android显存到内存拷贝耗时,memcpy速度太慢?掌握这个技术让内存拷贝效率成倍提升...
- 失去循环标记的Python,我这样实现跳出外层循环
- 矩阵乘法 c/c++代码
- 田志刚:个人知识管理常用软件、工具介绍
- Maven到底是个啥?——Maven深入理解
- (转)CGJ02、BD09、西安80、北京54、CGCS2000常用坐标系详解
- 深度学习baseline模型_深度学习模型在序列标注任务中的应用
- 移位运算为什么比乘法除法快
- 报错信息:Avoid mutating a prop directly since the value will be overwritten
- 数据库设计之商品表分析1
- D3.js-基础知识
- 2021-08-11 svg基础标签
热门文章
- 不同颜色坐标系的坐标转换
- 如何批量清理DWG文件?DWG文件清理教程
- 我的世界正版验证服务器地址,我的世界1.7.10服务器纯净地址大全
- linux文件复制粘贴权限,Linux 文件特殊权限
- 控制萤石云摄像头转头
- win7 微信 代理服务器设置,手把手为你讲解win7系统电脑登录多个微信的详细方法...
- 游戏检测的对抗与防护艺术
- windows7 照片查看器无法打开图片, windows提示因为可用内存不足,但我的内存4G?
- 阿里maven私服配置和作品上传
- Windows 启动 Idea 报错 if you already hava a 64-bit JDK ... 以及 failed to create jvm...