Solr DocValues详解
前言:
在Lucene4.x之后,出现一个重大的特性,就是索引支持DocValues,这对于广大的solr和elasticsearch用户,无疑来说是一个福音,这玩意的出现通过牺牲一定的磁盘空间带来的好处主要有两个:
(1)节省内存
(2)对排序,分组和一些聚合操作时能够大大提升性能
下面来详细介绍下DocValue的原理和使用场景
(一)什么是DocValues?
DocValues其实是Lucene在构建索引时,会额外建立一个有序的基于document => field value的映射列表;
(二)为什么要用DocValues ?
基于lucene的solr和es都是使用经典的倒排索引模式来达到快速检索的目的,简单的说就是建立 搜索词=》 文档id列表 这样的关系映射,
然后在搜索时,通过类似hash算法,来快速定位到一个搜索关键词,然后读取其的文档id集合,这就是倒排索引的核心思想,这样搜索数据
是非常高效快速的,当然它也是有缺陷的,假如我们需要对数据做一些聚合操作,比如排序,分组时,lucene内部会遍历提取所有出现在文档集合
的排序字段然后再次构建一个最终的排好序的文档集合list,这个步骤的过程全部维持在内存中操作,而且如果排序数据量巨大的话,非常容易就造成solr内存溢出和性能缓慢。
基于这个原因,在lucene4.x之后出现了docvalue这个新特性,在构建索引时会对开启docvalues的字段,额外构建一个已经排好序的文档到字段级别的一个列式存储映射,它减轻了在排序和分组时,对内存的依赖,而且大大提升了这个过程的性能,当然它也会耗费的一定的磁盘空间。
(三)什么时候应该用DocValues?
通过上面的剖析,散仙相信大家已经对DocValues有一个初步的了解了,至于它的应用场景,那么也非常明显了,总结起来主要以下几个方面:
1,需要聚合的字段,包括sort,agg,group,facet等
2,需要提供函数查询的字段
3,需要高亮的字段,这个确实能加速,但是不建议把高亮放在服务端程序做,建议放在前端实现,不容易出错而且总体性能比服务端高
4,需要参与自定义评分的字段,这个稍复杂,大多数人的场景中,不一定能用到,后面会单独写一篇文章介绍。
对于不需要参与上面任何一项的字段,可以选择关闭docvalues,这样可以节省一定的磁盘空间.
(四)DocValues的种类
在lucene的枚举类DocValuesType 中,我们可以看见它声明了六个常量:
1, NONE 不开启docvalue时的状态
2, NUMERIC 单个数值类型的docvalue主要包括(int,long,float,double)
3, BINARY 二进制类型值对应不同的codes最大值可能超过32766字节,
4, SORTED 有序增量字节存储,仅仅存储不同部分的值和偏移量指针,值必须小于等于32766字节
5, SORTED_NUMERIC 存储数值类型的有序数组列表
6, SORTED_SET 可以存储多值域的docvalue值,但返回时,仅仅只能返回多值域的第一个docvalue
通常有四种docvalue存储场景:
A: 字符串或UUID字段+单值 会选择SORTED作为docvalue存储
B: 字符串或UUID字段+多值 会选择SORTED_SET作为docvalue存储
C:数值或日期或枚举字段+单值 会选择NUMERIC 作为docvalue存储
D:数值或日期或枚举字段+多值 会选择SORTED_SET作为docvalue存储
注意,分词字段存储docvalue是没有意义的
(五)如何在Lucene,Solr,ElasticSearch中使用DocValues?
说完了概念方面的东西,下面来点实例的例子,来看下如何给索引加上docsvalue,只要加上docvalues后,排序,分组,聚合的时候
会自动使用docvalue提速,所以我们关注的重点是如何激活docvalue。
1,在原生Lucene中使用DocValues,这个稍麻烦,需要自定义组装,因为lucene是核心算法包,所以封装程度并不是很高,正是
由于这样,理解了lucene之后,再理解solr和elasticsearch是非常easy的。
下面是在lucene中存储docvalue例子,一个是string类型,一个是数值类型,分词类型在这里没有意义,不再提及:
- //数值存储例子
- 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();
2,在Solr中docvalue默认是全部关闭,比较严谨,大家可酌情开启
- <fieldname="easy_money"type="double"indexed="true"stored="true"docValues="true" />
3,在ElasticSearch中,默认docvalue全部激活,比较简单暴力,大家可酌情关闭一些不需要使用docvalue的字段,以节省磁盘空间
- "session_id":{"type":"string","index":"not_analyzed","doc_values":false}
最后再提一点,在和solr和es中,如果想要在自己写的插件中读取docvalue的值,读取方法和lucene的差不多,需要注意doule和float的的值转换
Solr DocValues详解的更多相关文章
- Solr部署详解
Solr部署详解 时间:2013-11-24 方式:转载 目录 1 solr概述 1.1 solr的简介 1.2 solr的特点 2 Solr安装 2.1 安装JDK 2.2 安装Tomcat 2.3 ...
- Solr系列三:solr索引详解(Schema介绍、字段定义详解、Schema API 介绍)
一.Schema介绍 1. Schema 是什么? Schema:模式,是集合/内核中字段的定义,让solr知道集合/内核包含哪些字段.字段的数据类型.字段该索引存储. 2. Schema 的定义方式 ...
- Solr系列五:solr搜索详解(solr搜索流程介绍、查询语法及解析器详解)
一.solr搜索流程介绍 1. 前面我们已经学习过Lucene搜索的流程,让我们再来回顾一下 流程说明: 首先获取用户输入的查询串,使用查询解析器QueryParser解析查询串生成查询对象Query ...
- Solr高亮详解
hl.fl: 用空格或逗号隔开的字段列表.要启用某个字段的highlight功能,就得保证该字段在schema中是stored.如果该参数未被给出,那么就会高亮默认字段 standard handle ...
- Solr查询详解
前言:上节是关于Solr的开发准备工作:.NET开发过程中的全文索引使用技巧之Solr(http://www.cnblogs.com/johnwood/p/3447242.html) 这节重点是讲So ...
- Windows下安装solr步骤详解
Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引:也可以通过Http Get操 ...
- Solr系列六:solr搜索详解优化查询结果(分面搜索、搜索结果高亮、查询建议、折叠展开结果、结果分组、其他搜索特性介绍)
一.分面搜索 1. 什么是分面搜索? 分面搜索:在搜索结果的基础上进行按指定维度的统计,以展示搜索结果的另一面信息.类似于SQL语句的group by 分面搜索的示例: http://localhos ...
- Solr相关概念详解:SolrRequestHandler
转自:http://www.cnblogs.com/chenying99/archive/2012/07/24/2607339.html 1. standard (StandardRequestHan ...
- Solr安装入门、查询详解
Solr安装入门:http://www.importnew.com/12607.html 查询详解:http://www.360doc.com/content/14/0306/18/203871_35 ...
随机推荐
- webpack 打包产生的文件名中,hash、chunkhash、contenthash 的区别
table th:first-of-type { width: 90px; } hash 类型 区别 hash 每一次打包都会生成一个唯一的 hash chunkhash 根据每个 chunk 的内容 ...
- 自然语言处理之:搭建基于HanLP的开发环境(转)
环境搭建比FNLP的简单,具体参考:https://github.com/hankcs/HanLP 各个版本的下载:https://github.com/hankcs/HanLP/releases 完 ...
- Vivado HLS初识---阅读《vivado design suite tutorial-high-level synthesis》(2)
Vivado HLS初识---阅读<vivado design suite tutorial-high-level synthesis>(2) 1.实验目的 2.启动命令行 将命令行切换 ...
- 银行卡所属公司判断 参考自https://blog.csdn.net/well2049/article/details/79429130
在网上找到了一个银行卡的验证,通过阿里的支付宝接口进行校验,能够准确识别是否存在,归属行,卡号类型是储蓄卡(DC)还是信用卡(CC). 接口api:需要传入的2个参数,卡号cardNo和cardBin ...
- 【转】使用kettle工具遇到的问题汇总及解决方案
使用kettle工具遇到的问题汇总及解决方案 转载文章版权声明:本文转载,原作者薄海 ,原文网址链接 http://blog.csdn.net/bohai0409/article/details/ ...
- jQuery实现商品详情 详细参数页面切换
利用index实现: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- Excel技巧--批量生成指定名称的文件夹
当我要按excel表当中的名字来批量生成文件夹时,手动一个个制作很麻烦(特别是成百上千个时).于是我们可以这么做: 1.在名字右侧建立公式:"MD "&A2. 2.将公式拖 ...
- CentOS 7.4 初次手记:第一章 Linux守护进程(daemon)
第一节 init & sysvinit 6 I sysvinit 运行顺序... 6 II Sysvinit和系统关闭... 7 III Sysvinit 的小结... 7 IV 运行级别.. ...
- DEVC怎么建工程
1.DEVC建工程 1.1 新建项目 打开文件,选择新建-->项目-->ConsoleApplication(控制台程序),输入项目名,选择保存路径.(单独建一个文件夹存放) 项目建成功后 ...
- pytest.3.Assert
From: http://www.testclass.net/pytest/assert/ Assert就是断言,每个测试用例都需要断言. 与unittest不同,pytest使用的是python自带 ...