• lucene 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.   
    8.   Document doc=new Document();  
    9.   //添加string字段  
    10.   doc.add(new SortedDocValuesField("id",new BytesRef("01011")));  
    11.   //添加数值类型的字段  Float,Doule需要额外转成bit位才能存储,Interger和Long则不需要  
    12.   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}  


    摘自:http://qindongliang.iteye.com/blog/2297280

  • 相关阅读:
    Java Arrays.asList注意事项
    从给定的N个正数中选取若干个数之和最接近M
    java 8 foreach获取索引
    更优雅地关闭资源
    idea 下获取路径下文件的方法
    IDEA类和方法注释模板设置(非常详细)
    503 Error: need EHLO and AUTH first
    fatal error C1083: Cannot open include file: 'openssl/opensslv.h'
    'pip' 不是内部或外部命令
    JS中every()和some()的用法
  • 原文地址:https://www.cnblogs.com/bonelee/p/6669263.html
Copyright © 2020-2023  润新知