ElasticSearch搜索引擎:常用的存储mapping配置项 与 doc_values详细介绍

ElasticSearch搜索引擎:常用的存储mapping配置项 与 doc_values详细介绍

一、ES的数据存储结构:

ES底层使用 Lucene 存储数据,Lucene 的索引包含以下部分:

A Lucene index is made of several components: an inverted index, a bkd tree, a column store (doc values), a document store (stored fields) and term vectors, and these components can communicate thanks to these doc ids.

 其中:

  • inverted index:倒排索引。
  • bkd tree: Block k-d tree,用于在高维空间内做索引,如地理坐标的索引。
  • column store:doc values,列式存储,批量读取连续的数据以提高排序和聚合的效率。
  • document store:Store Fileds,行式存储文档,用于控制 doc 原始数据的存储,其中占比最大的是 source 字段。
  • term vectors:用于存储各个词在文档中出现的位置等信息。

 

二、ES常见配置项说明:

在很多场合下,我们并不需要存储上述全部信息,因此可以通过设置 mappings 里面的属性来控制哪些字段是我们需要存储的、哪些是不需要存储的。而 ES 的 mapping 中有很多设置选项,这些选项如果设置不当,有的可能浪费存储空间,有的可能导致无法使用 Aggregation,有的可能导致不能检索。下面就简单介绍下 ES 中常见的存储与检索的 mapping 配置项:

配置项 作用 注意事项 默认值
_all 提供跨字段全文检索

(1)会占用额外空间,把 mapping 中的所有字段通过空格拼接起来做索引,在跨字段全文检索才需要打开;

(2)在 v6.0+已被弃用,v7.0会正式移除,可以使用 [copy_to] 来自定义组合字段

关闭
_source 存储 post 提交到ES的原始 json 内容

(1)会占用很多存储空间。数据压缩存储,读取会有额外解压开销。

(2)不需要读取原始字段内容可以考虑关闭,但关闭后无法 reindex

开启
store 是否单独存储该字段 (1)会占用额外存储空间,与 source 独立,同时开启 store 和 source 则会将该字段原始内容保存两份,不同字段单独存储,不同字段的数据在磁盘上不连续,若读取多个字段则需要查询多次,如需读取多个字段,需权衡比较 source 与 store 效率 关闭
doc_values 支持排序、聚合 会占用额外存储空间,与 source 独立,同时开启 doc_values 和 _source 则会将该字段原始内容保存两份。doc_values 数据在磁盘上采用列式存储,关闭后无法使用排序和聚合 开启
index 是否加入倒排索引 关闭后无法对其进行搜索,但字段仍会存储到 _source 和 doc_values,字段可以被排序和聚合 开启
enabled 是否对该字段进行处理 关闭后,只在 _source中存储,类似 index 与 doc_values 的总开关 开启

在ES的 mapping 设置里,all,source 是 mapping 的元数据字段(Meta-Fields),store、doc_values、enabled、index 是 mapping 参数。

1、_all:

all 字段的作用是提供跨字段查询的支持,把 mapping 中的所有字段通过空格拼接起来做索引。ES在查询的过程中,需要指定在哪一个field里面查询。

{
    “name”: “smith”,
    “email”: "John@example.com"
}

用户在查询时,想查询叫做 John 的人,但不知道 John 出现在 name 字段中还是在 email 字段中,由于ES是为每一个字段单独建立索引,所以用户需要以 John 为关键词发起两次查询,分别查询name字段和email字段。

如果开启了 all 字段,则ES会在索引过程中创建一个虚拟的字段 all,其值为文档中各个字段拼接起来所组成的一个很长的字符串(例如上面的例子,all 字段的内容为字符串 “smith John@example.com”)。随后,该字段将被分词打散,与其他字段一样被收入倒排索引中。由于 all 字段包含了所有字段的信息,因此可以实现跨字段的查询,用户不用关心要查询的关键词在哪个字段中。

由于该字段的内容都来自 source 字段,因此默认情况下,该字段的内容并不会被保存,可以通过设置 store 属性来强制保存 all 字段。开启 all 字段,会带来额外的CPU开销和存储,如果没有使用到,可以关闭 all 字段。

2、_source:

source 字段用于存储 post 到 ES 的原始 json 文档。为什么要存储原始文档呢?因为 ES 采用倒排索引对文本进行搜索,而倒排索引无法存储原始输入文本。一段文本交给ES后,首先会被分析器(analyzer)打散成单词,为了保证搜索的准确性,在打散的过程中,会去除文本中的标点符号,统一文本的大小写,甚至对于英文等主流语言,会把发生形式变化的单词恢复成原型或词根,然后再根据统一规整之后的单词建立倒排索引,经过如此一番处理,原文已经面目全非。因此需要有一个地方来存储原始的信息,以便在搜到这个文档时能够把原文返回给查询者。

那么一定要存储原始文档吗?不一定!如果没有取出整个原始 json 结构体的需求,可以在 mapping 中关闭 source 字段或者只在 source 中存储部分字段(使用store)。 但是这样做有些负面影响:

  • (1)不能获取到原文
  • (2)无法reindex:如果存储了 source,当 index 发生损坏,或需要改变 mapping 结构时,由于存在原始数据,ES可以通过原始数据自动重建index,如果不存 source 则无法实现
  • (3)无法在查询中使用script:因为 script 需要访问 source 中的字段

3、store:

store 决定一个字段是否要被单独存储。大家可能会有疑问,source 里面不是已经存储了原始的文档嘛,为什么还需要一个额外的 store 属性呢?原因如下:

(1)如果禁用了 source 保存,可以通过指定 store 属性来单独保存某个或某几个字段,而不是将整个输入文档保存到 source 中。

(2)如果 source 中有长度很长的文本(如一篇文章)和较短的文本(如文章标题),当只需要取出标题时,如果使用 source 字段,ES需要读取整个 source 字段,然后返回其中的 title,由此会引来额外的IO开销,降低效率。此时可以选择将 title 的 store 设置为true,在 source 字段外单独存储一份。读取时不必在读取整 source 字段了。但是需要注意,应该避免使用 store 查询多个字段,因为 store 的存储在磁盘上不连续,ES在读取不同的 store 字段时,每个字段的读取均需要在磁盘上进行查询操作,而使用 source 字段可以一次性连续读取多个字段。

4、doc_values:

倒排索引可以提供全文检索能力,但是无法提供对排序和数据聚合的支持。doc_values 本质上是一个序列化的列式存储结构,适用于聚合(aggregations)、排序(Sorting)、脚本(scripts access to field)等操作。默认情况下,ES几乎会为所有类型的字段存储doc_value,但是 text 或 text_annotated 等可分词字段不支持 doc values 。如果不需要对某个字段进行排序或者聚合,则可以关闭该字段的doc_value存储。

5、index:

控制倒排索引,用于标识指定字段是否需要被索引。默认情况下是开启的,如果关闭了 index,则该字段的内容不会被 analyze 分词,也不会存入倒排索引,即意味着该字段无法被搜索。

6、enabled:

这是一个 index 和 doc_value 的总开关,如果 enabled 设置为false,则这个字段将会仅存在于 source 中,其对应的 index 和 doc_value 都不会被创建。这意味着,该字段将不可以被搜索、排序或者聚合,但可以通过 source 获取其原始值。

7、term_vector:

在对文本进行 analyze 的过程中,可以保留有关分词结果的相关信息,包括单词列表、单词之间的先后顺序、单词在原文中的位置等信息。查询结果返回的高亮信息就可以利用其中的数据来返回。默认情况下,term_vector是关闭的,如有需要(如加速highlight结果)可以开启该字段的存储。

 

三、doc_values 详细说明:

1、doc_values 的作用:

基于 lucene 的 solr 和 es 都是使用倒排索引实现快速检索的,也就是通过建立 “搜索关键词 ==>文档ID列表” 的关系映射实现快速检索,但是倒排索引也是有缺陷的,比如我们需要字段值做一些排序、分组、聚合操作,lucene 内部会遍历提取所有出现在文档集合的排序字段,然后再次构建一个最终的排好序的文档集合list,这个步骤的过程全部维持在内存中操作,而且如果排序数据量巨大的话,非常容易就造成solr内存溢出和性能缓慢。

doc values 就是在构建倒排索引时,会对开启 doc values 的字段额外构建一个有序的 “document文档 ==> field value“ 的列式存储映射,从而实现对指定字段进行排序和聚合时对内存的依赖,提升该过程的性能。默认情况下每个字段的 doc values 都是开启的,当然 doc values 也会耗费一定的磁盘空间。

另外 doc values 保存在操作系统的磁盘中,当 doc values 大于节点的可用内存,ES 可以从操作系统页缓存中加载或弹出,从而避免发生 JVM 内存溢出的异常,docValues 远小于节点的可用内存,操作系统自然将所有Doc Values存于内存中(堆外内存),有助于快速访问。

2、doc_values 与 source 的区别?使用 docvalue_fields 检索指定的字段?

post 提交到 ES 的原始 Json 文档都存储在 source 字段中,默认情况下,每次搜索的命中结果都包含文档 source,即使仅请求少量字段,也必须加载并解析整个 source 对象,而 source 每次使用时都必须加载和解析,所以使用 source 非常慢。为避免该问题,当我们只需要返回相当少的支持 doc_values 的字段时,可以使用 docvalue_fields 参数获取选定字段的值。

doc values 存储与 _source 相同的值,但在磁盘上基于列的结构中进行了优化,以进行排序和汇总。由于每个字段都是单独存储的,因此 Elasticsearch 仅读取请求的字段值,并且可以避免加载整个文档 _source。通过 docvalue_fields 可以从建好的列式存储结果中直接返回字段值,毕竟 source 是从一大片物理磁盘去,理论上从 doc values 处拿这个字段值会比 source 要快一点,页面抖动少一点。

3、如何在 ES 中使用 doc values?

doc values 通过牺牲一定的磁盘空间带来的好处主要有两个:

  • 节省内存
  • 提升排序,分组等聚合操作的性能

那么我们如何使用 doc values 呢?

(1)我们首先关注如何激活 doc values,只要开启 doc values 后,排序,分组,聚合的时候会自动使用 doc values 提速。在 ElasticSearch 中,doc values 默认是开启的,比较简单暴力,我们也可以酌情关闭一些不需要使用 doc values 的字段,以节省磁盘空间,只需要设置 doc_values 为 false 就可以了,如下:

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

(2)使用 docvalue_fields 的检索指定的字段:

GET my-index-000001/_search
{
  "query": {
    "match": {
      "user.id": "kimchy"
    }
  },
  "docvalue_fields": [
    "user.id",
    "http.response.*", 
    {
      "field": "date",
      "format": "epoch_millis" 
    }
  ]
}

 

ES搜索指定字段的不同方式,详情请见官网:https://www.elastic.co/guide/en/elasticsearch/reference/7.x/search-fields.html#search-fields

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/114590.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Ubuntu安装五笔输入法「建议收藏」

    Ubuntu安装五笔输入法「建议收藏」学习Ubuntu 环境VirtualBox 准备好Ubuntu系统后,这里下载的是12.04LTS版本1.安装五笔输入法在网上找资料,通过Ibus平台安装五笔输入法发现本操作系统已安装了Ibus,然后直接安装五笔IBUS五笔:sudoapt-getinstallibus-table-wubi2.设置输入法ibus-setup

  • 最新最全的微信小程序入门学习教程,微信小程序零基础入门到精通

    最新最全的微信小程序入门学习教程,微信小程序零基础入门到精通从今天开始就来带领大家学习微信小程序了,只要你跟着我一步步来,相信你也可以上线一款属于自己的微信小程序一,认识小程序微信⼩程序,简称⼩程序,英⽂名MiniProgramMiniProgram,是⼀种不需要下载安装即可使⽤的应⽤,它实现了应⽤“触⼿可及”的梦想,⽤⼾扫⼀扫或搜⼀下即可打开应⽤1-1,微信小程序的优势1.微信有海量⽤⼾,⽽且粘性很⾼,在微信⾥开发产品更容易触达⽤⼾;2.推⼴app或公众号的成本太⾼。3.开发适配成本低。4.容易⼩规模试错,然后快速迭代。5.跨平台。

  • [系统审计]SAP HANA 中的系统审计策略管理

    [系统审计]SAP HANA 中的系统审计策略管理

  • h3c bios密码_日本服务器ip端口密码

    h3c bios密码_日本服务器ip端口密码版本Ladon>=7.1139端口NetBIOSFileandPrintSharing通过这个端口进入的连接试图获得NetBIOS/SMB服务。这个协议被用于Windows”文件和打印机共享”和SAMBA。IPC$通信Windows系统中的netuseipc整个通信过程,先445−>137−>139验证,当你开启防火墙禁用445,发现系统命令就无法连接IPC了,根本没机会走到139,所以使用系统自带命令连接的ipc整个通信过程,先445->137->

  • java商城_国内三款知名java商城系统:shop++、shopnc、javashop浅析

    java商城_国内三款知名java商城系统:shop++、shopnc、javashop浅析在众多商家决定搭建一个独立的网上商城系统时,就开始苦恼,市面上这么多商城系统到底该选哪一个才好呢?我们又如何选到靠谱又实用的商城系统呢?国内三款知名java商城系统最近我也在了解商城系统的应用程序,市面上的商城系统颇为混杂,以下是本人针对国内三款知名java商城系统的(shop++、shopnc、javashop)分析,排名不分先后。SHOP++关注SHOP++有些时间了,从中体验了他们的6.0版…

  • 自动化运维平台的流程草图「建议收藏」

    自动化运维平台的流程草图「建议收藏」对于平台里面的几个地方一直没大理清楚,所以想了几种办法,一种是蒙着头继续做,想到哪里做到哪里,结果做的时候发现很多东西都没有规划好,很容易从这个死胡同调入另一个死胡同,所以进度不能保证,质量不能保证。 第二个是…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号