`
qindongliang1922
  • 浏览: 2183584 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117521
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:125919
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:59881
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71297
社区版块
存档分类
最新评论

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

              //数值存储例子
                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的的值转换。


有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。
技术债不能欠,健康债更不能欠, 求道之路,我们同行。


1
0
分享到:
评论
2 楼 qindongliang1922 2018-06-19  
粟谷_sugu 写道
不太理解“分词字段存储docvalue是没有意义的”,这句话,请问有什么原因或者文章可以解释一下嘛?


douvalue主要用来提升排序,聚合字段性能,是基于单个term也就是关键词的,所以用于分词的字段是没有很大的意义的
1 楼 粟谷_sugu 2018-06-13  
不太理解“分词字段存储docvalue是没有意义的”,这句话,请问有什么原因或者文章可以解释一下嘛?

相关推荐

    Lucene DocValues介绍

    介绍了Lucene 7.5.0版本的 DocValues,文档中的链接包含了SortedSetDocValues、SortedDocValues、NumericDocValues、SortedNumericDocValues、BinaryDocValues

    使用Lucene对doc、docx、pdf、txt文档进行全文检索功能的实现 - 干勾鱼的CSDN博客 - CSDN博客1

    在Java开发中,Lucene被广泛用于实现文件的全文检索功能,包括对doc、docx、pdf、txt等常见格式文档的文本内容检索。在本文中,我们将探讨如何使用Lucene对这些文件类型进行全文检索的实现。 首先,为了实现全文...

    lucene对doc.xlsx操作包

    然而,传统的Lucene主要针对纯文本文件进行操作,而现代业务中,如doc、xlsx等办公文档的处理需求日益增加。本文将深入探讨如何使用Lucene处理doc.xlsx文档,并介绍相关的包和工具。 一、Lucene简介与功能 Lucene...

    lucene.NET 中文分词

    在Lucene.NET中,为了支持中文分词,通常需要结合第三方分词器,如IK Analyzer、HanLP、jieba.NET等。这些分词器具备丰富的词汇库和优秀的分词算法,能有效地对中文文本进行拆分。 - **IK Analyzer**:是一个开源的...

    lucene.net基本应用(doc)

    - 如果在多个线程中使用 Lucene,需要考虑同步和锁定机制,以避免数据不一致。 - 选择合适的 `Analyzer`,根据实际文本语言和需求进行定制。 - 考虑定期优化索引,尤其是在大量更新后,以保持最佳搜索性能。 - ...

    Lucene中的FST算法描述

    在信息检索和存储系统中,Lucene是一个开源的全文搜索引擎库,广泛应用于各种需要全文搜索功能的软件项目中。为了高效地处理和检索存储的词项(term),Lucene使用了FST(有限状态转换器,Finite State Transducer)...

    Lucene技术文档doc

    **Lucene技术文档doc** **一、Lucene简介** Lucene是Apache软件基金会下的Jakarta项目组的一个核心项目,它是一款高性能、可扩展的全文检索引擎库。作为一个开源的Java库,Lucene提供了完整的搜索功能,包括索引、...

    Lucene中文分词器包

    来自“猎图网 www.richmap.cn”基于IKAnalyzer分词算法的准商业化Lucene中文分词器。 1. 正向全切分算法,42万汉字字符/每秒的处理能力(IBM ThinkPad 酷睿I 1.6G 1G内存 WinXP) 2. 对数量词、地名、路名的...

    Lucene中文分词器组件

    Lucene是一个强大的全文检索库,广泛应用于搜索引擎开发和其他信息检索系统中。它提供了高效、可扩展的文本搜索功能,但是默认情况下并不支持中文处理。为了在Lucene中处理中文文本,我们需要引入专门的中文分词器...

    Lucene 3.0.2 API DOC

    Lucene 3.0.2 API DOC CHM 是开发的必备工具之一

    lucene 3.0 API 中文帮助文档 chm

    lucene 3.0 API中文帮助,学习的人懂得的

    lucene-core-7.2.1-API文档-中文版.zip

    赠送jar包:lucene-core-7.2.1.jar; 赠送原API文档:lucene-core-7.2.1-javadoc.jar; 赠送源代码:lucene-core-7.2.1-sources.jar;...人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。

    Lucene中文切词(完整版)

    Lucene是一个强大的全文检索库,它被广泛应用于各种信息检索和搜索引擎系统中。这个“完整版”可能指的是提供了一个完整的项目,包含了源代码,使得用户可以直接运行并理解其工作原理。 描述中的“又完整工程,源...

    lucene 中文分词 庖丁解牛

    其中,Apache Lucene作为一个开源的全文检索库,被广泛应用于各种项目中,尤其对于处理中文文本,分词是其关键的一环。本文将深入探讨如何在Lucene中高效地进行中文分词,借助“庖丁解牛”的概念,以求在理解与应用...

    lucene 3.0 API 中文帮助文档

    1. **Analyzer**: 分析器是Lucene中的核心组件之一,负责将输入的文本分解成可搜索的词项(tokens)。在3.0版本中,Lucene提供了多种预定义的Analyzer,如StandardAnalyzer,它们可以处理不同语言的文本。 2. **...

    lucene分组查询优化facet

    Lucene的分组查询(Faceting)是通过对索引中的文档进行多级分类来实现的。它首先会计算每个分面值的文档频率,然后对匹配查询条件的文档进行分组计数。这个过程涉及到倒排索引的遍历和统计,因此在处理大量数据时...

    lucene +中文分词

    Lucene 与中文分词的结合

    lucene,lucene教程,lucene讲解

    lucene,lucene教程,lucene讲解。 为了对文档进行索引,Lucene 提供了五个基础的类 public class IndexWriter org.apache.lucene.index.IndexWriter public abstract class Directory org.apache.lucene.store....

    如何使用Lucene的中文分词搜索

    此外,LuceneDB.java可能包含了与数据库交互的部分,将数据库中的数据导入到Lucene索引中,或者从索引中获取结果后更新到数据库。这部分代码可能涉及到JDBC操作和事务管理,具体实现会根据实际需求和数据库类型有所...

Global site tag (gtag.js) - Google Analytics