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类型,一个是数值类型,分词类型在这里没有意义,不再提及:

Java代码  

  1. //数值存储例子
  2. FieldType num=new FieldType();
  3. num.setStored(true);//设置存储
  4. num.setIndexOptions(IndexOptions.DOCS);//设置索引类型
  5. num.setNumericType(NumericType.DOUBLE);//数值类型
  6. num.setDocValuesType(DocValuesType.NUMERIC);//DocValue类型
  7. Document doc=new Document();
  8. //添加string字段
  9. doc.add(new SortedDocValuesField("id",new BytesRef("01011")));
  10. //添加数值类型的字段  Float,Doule需要额外转成bit位才能存储,Interger和Long则不需要
  11. doc.add(new DoubleField("price", Double.doubleToRawLongBits(25.258), num));

如何读取:

Java代码  

  1. //读取索引文件
  2. DirectoryReader reader=DirectoryReader.open(FSDirectory.open(Paths.get(indexDir)));
  3. //如果有多个段需要merge成一个,获取第一个进行测试,本例中仅仅就有一个段
  4. SortedDocValues str = DocValues.getSorted(reader.leaves().get(0).reader(), "id");
  5. //数值类型
  6. NumericDocValues db = DocValues.getNumeric(reader.leaves().get(0).reader(), "price");
  7. //读取字符串类型的ByteRef然后打印其内容
  8. System.out.println("id:"+str.get(0).utf8ToString());
  9. //注意此处,要与类型对应,如果是Float,则需要Float.intBitsToFloat((int)db.get(0))进行位数还原
  10. System.out.println("price: "+Double.longBitsToDouble(db.get(0)));
  11. reader.close();

2,在Solr中docvalue默认是全部关闭,比较严谨,大家可酌情开启

Java代码  

  1. <fieldname="easy_money"type="double"indexed="true"stored="true"docValues="true"  />

3,在ElasticSearch中,默认docvalue全部激活,比较简单暴力,大家可酌情关闭一些不需要使用docvalue的字段,以节省磁盘空间

Java代码  

  1. "session_id":{"type":"string","index":"not_analyzed","doc_values":false}

最后再提一点,在和solr和es中,如果想要在自己写的插件中读取docvalue的值,读取方法和lucene的差不多,需要注意doule和float的的值转换

原文地址:https://www.cnblogs.com/cuihongyu3503319/p/9522892.html

时间: 2024-10-28 20:47:41

Solr DocValues详解的相关文章

Solr查询详解

一. 查询参数说明 在做solr查询的时候,solr提供了很多参数来扩展它自身的强大功能!以下是使用频率最高的一些参数! 1.常用 q - 查询字符串,这个是必须的.如果查询所有*:* ,根据指定字段查询(Name:张三 AND Address:北京) fq - (filter query)过虑查询,作用:在q查询符合结果中同时是fq查询符合的,例如:q=Name:张三&fq=CreateDate:[20081001 TO 20091031],找关键字mm,并且CreateDate是200810

Solr相关概念详解:SolrRequestHandler

转自:http://www.cnblogs.com/chenying99/archive/2012/07/24/2607339.html 1. standard (StandardRequestHandler) 标准查询分析器使用SolrQuerySyntax通过q参数来指定查询,它要求被很好的组织(Formed),或返回一个异常.对于精确查询和任意复杂的查询,使用Standard效果很好. 2. dismax ( DismaxRequestHandler ) dismax查询分析器是一个为用户

【Solr】索引库查询界面详解

目录 索引库查询界面详解 回到顶部 索引库查询界面详解 q:主查询条件.完全支持lucene语法.还进行了扩展. fq:过滤查询.是在主查询条件查询结果的基础上进行过滤.例如:product_price:[10 TO 20] sort:排序条件.排序的域asc.如果有多个排序条件使用半角逗号分隔. start, rows:分页处理.Start起始记录rows每页显示的记录条数. fl:返回结果中域的列表.使用半角逗号分隔. df:默认搜索域. wt:响应结果的数据格式,可以是json.xml等.

指尖上的电商---(6)solrconfig.xml配置详解

solrconfig.xml配置文件主要定义了SOLR的一些处理规则,包括索引数据的存放位置,更新,删除,查询的一些规则配置. 可以在tomcat的安装路径下找到这个文件C:\Program Files\Apache Software Foundation\Tomcat 8.0\solr\collection1\conf 1.datadir节点 1.<dataDir>${solr.data.dir:d:/Server/Solr/data}</dataDir>定义了索引数据和日志文件

elasticsearch系列二:索引详解(快速入门、索引管理、映射详解、索引别名)

一.快速入门 1. 查看集群的健康状况 http://localhost:9200/_cat http://localhost:9200/_cat/health?v 说明:v是用来要求在结果中返回表头 状态值说明 Green - everything is good (cluster is fully functional),即最佳状态Yellow - all data is available but some replicas are not yet allocated (cluster i

6.跟我学solr---请求参数详解

简介 前面我们在讲SolrRequestHandler和QueryResponseWriter的时候提到过两个参数'qt'和'wt",这两个参数是分别用于选择对应的SolrRequestHandler和QueryResponseWriter的.solr定义了很多类似的参数,它们都分别属于某个大类中,例如"qt"和"wt"就属于CoreQueryParameters.下面罗列一下solr的所有参数列表,来源于solr官网.下面笔者会一一给大家讲解这些参数的作

4.跟我学solr---SolrRequestHandler详解

概述 我们在使用solr admin在做查询的时候,可以看到Request-Hander(qt)输入栏中有"/select"这样一个uri,当我们点击查询的时候所发起的请求是这样的,http://localhost:8080/solr/collection1/select?q=feature&wt=json&indent=true&_=1399167234058,我们可以看到"/select"被自动地加到请求的url里面.那么solr服务在接

javascript AJAX与Comet详解

          博客专家福利      [限时活动]建专辑得大奖       专访荣浩:流程的永恒之道      当青春遇上互联网,能否点燃你的创业梦      推荐有礼--找出您心中的技术大牛 javascript AJAX与Comet详解 分类: javascript2012-12-24 17:39 367人阅读 评论(0) 收藏 举报 XMLHttpRequest对象 在IE5中,XHR对象是通过MSXML库中的ActiveX对象实现的.在IE中可能会遇到三种不同版本的XHR对象,即M

8.跟我学solr---UpdateRequestProcessor详解

简介 java web开发的同学应该很熟悉,在开发中经常会使用filter来处理请求中的一些切面需求.solr也提供类似的一种链式结构的handler来满足在添加数据索引请求的时候,通过切片的形式,增加一个handler来对请求进行加工. 配置在SORL_HOME\collection1\conf\solrconfig.xml文件中,配置方式如下: <updateRequestProcessorChain name="mychain" default="true&quo