Elasticsearch之深入聚合查询

1、正排索引

1.1 正排索引(doc values )和倒排索引

概念:从广义来说,doc values 本质上是一个序列化的 列式存储 。列式存储 适用于聚合、排序、脚本等操作,所有的数字、地理坐标、日期、IP 和不分词( not_analyzed )字符类型都会默认开启,不支持textannotated_text类型

区别:

  • 倒排:倒排索引的优势是可以快速查找包含某个词项的文档有哪些。如果用倒排来确定哪些文档中是否包含某个词项就很鸡肋。
  • 正排:正排索引的优势在于可以快速的查找某个文档里包含哪些词项。同理,正排不适用于查找包含某个词项的文档有哪些。

倒排索引和正排索引均是在index-time时创建,保存在 Lucene文件中(序列化到磁盘)。

1.2 正排索引的数据结构

1.2.1 doc values

doc values是正排索引的基本数据结构之一,其存在是为了提升排序和聚合效率,默认true,如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc values值以节省磁盘空间。

1.2.2 fielddata:

概念:查询时内存数据结构,在首次用当前字段聚合、排序或者在脚本中使用时,需要字段为fielddata数据结构,并且创建倒排索引保存到堆中。与 doc value 不同,当没有doc value的字段需要聚合时,需要打开fielddata,然后临时在内存中建立正排索引,fielddata 的构建和管理发生在 JVM Heap中。Fielddata默认是不启用的,因为text字段比较长,一般只做关键字分词和搜索,很少拿它来进行全文匹配和聚合还有排序。

语法:

PUT /<index>/_mapping
{
  "properties": {
    "tags": {
      "type": "text",
      "fielddata": true  //true:开启fielddata;		false:关闭fielddata
    }
  }
}

**深层解读(独家):**doc values是文档到词项的映射 inverted是词项到文档id的映射从原理上讲 先说倒排索引为什么不适合聚合,你无法通过倒排索引确定doc的总数量,并且因为倒排索引默认会执行analysis,即使聚合,结果也可能不准确,所以你还要创建not_analyzed字段,徒增磁盘占用,举个最简单的例子:假如有一张商品表,每个商品都有若干标签,我们执行了以下查询

GET product/_search
{
  "query": {
    "match": {
      "tags": "性价比"
    }
  },
  "aggs": {
    "tag_terms": {
      "terms": {
        "field": "tags.keyword"
      }
    }
  }
}

这段聚合查询的意思 查询包含“性价比”这个标签商品的所有标签,在执行agg的时候 我们使用倒排索引,那么语义将是这样的:在倒排索引中扫描逐个term,看看这个term对用的倒排表中对应的doc的标签 是否包含“性价比”,如果包含,则记录,由于我们不确定下面一个term是否符合条件,所以我们就要一个一个的判断,所以就造成了扫表。如果使用正排索引,而正排索引的指的是,doc中包含了哪些词项,也就是当前doc_id=>当前字段所包含的所有词项的映射,我们要查找的是符合条件的doc中所有的标签,那么我们直接根据key(doc_id)去拿values(all terms)就可以了,所以就不用扫表。所以聚合查询使用正排索引效率高本质是两种数据结构的区别 和结不结合倒排索引没有关系,结合倒排索引只是预先进行了数据筛选。以上是正排索引在原理上对聚合查询友好的原因 下面我说一下关于两种数据结构在数据压缩上的不同,doc values是一种序列化的列式存储结构,其values其中也包含了词频数据。而这种结构是非常有利于数据压缩的,参考第二版VIP课程中的FOR和RBM压缩算法,因为Lucene底层读取文件的方式是基于mmap的,原理是上是从磁盘读取到OS cache里面进行解码的,使用正排索引的数据结构,由于其列式存储的数据和posting list一样可以被高效压缩,所以这种方式极大的增加了从磁盘中读取的速度,因为体积小了,然后把数据在OS Cache中进行解码

2、三角选择原则

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3、基数聚合:Cardinality

3.1 易并行算法和不易并行算法

3.1.1 易并行算法

如:Max、Min、Avg、Sum等指标函数,通常只需要在多个分片中计算一个值进行汇总计算,因此不必消耗过多内存资源。(参考深度分页原理)

3.1.2 不易并行算法

如:Cardinality函数,由于无法在不同分片中保证数据是否重合,因此将消耗更多的内存用于数据汇总进行基数聚合,尤其是高基聚合。

3.2 高基数与低基数聚合

高基数:性能低

低基数:性能高

3.3 Cardinality精度内存换算

3.3.1 precision_threshold参数

ES在执行Cardinality聚合的时候,通过precision_threshold参数以内存换精度,默认3000,最大值40000,设置再大的值,实际也最高只能是4W,当小于precision_threshold设置的时候,精度接近100%,当大于此设置的时候,即使数据量有几百万,误差也只是1-6%。

注意:precision_threshold设置较高阈值对低基数聚合时有显著效果,而对高基数聚合是并无显著效果,反而会占用大量的资源,适得其反。

3.3.2 内存精度换算单位

内存消耗 <=> precision_threshold * 8 个Byte,比如 precision_threshold = 1000,内存消耗约 8KB。

3.4 HyperLogLog++介绍

HyperLogLog++(HLL)算法是依赖于field value计算hash,在做cardinality运算的时候,ES会动态为每一个field value计算hash用于提升聚合性能。

3.5 低基聚合的优化方案:maper-murmur3

3.5.1 作用

提升低基聚合的查询性能,副作用是消耗较大磁盘空间。

3.5.2 原理

maper-murmur3提升低基聚合的原理就是通过预先为字段值计算hash,在做cardinality计算的时候,使用提前准备好的hash值参与计算,避免了动态运算从而节省性能,建议在字段基数较大并且可能会有大量重复值得时候使用,这样可能会产生显著的性能提升,不然可能不但不会带来显著的性能提升,而且会徒增磁盘消耗,得不偿失。

3.5.3 安装与使用

安装

bin/elasticsearch-plugin install mapper-murmur3

使用

PUT <index>
{
  "mappings": {
    "properties": {
      "type": {
        "type": "keyword",
        "doc_values": true,
        "fields": {
          "hash": {
            "type": "murmur3"
          }
        }
      }
    }
  }
}
POST /index/_search?size=0
{
  "aggs": {
    "type_count": {
      "cardinality": {
        "field": "type.hash"
      }
    }
  }
}

4、深度优先(DFS)和广度优先(BFS)

4.1 概念和基本原理

背景:Terms 桶基于我们的数据动态构建桶;它并不知道到底生成了多少桶。 大多数时候对单个字段的聚合查询还是非常快的, 但是当需要同时聚合多个字段时,就可能会产生大量的分组,最终结果就是占用 es 大量内存,从而导致 OOM 的情况发生。

在Elasticsearch中,对于具有许多唯一术语和少量所需结果的字段,延迟子聚合的计算直到顶部父级聚合被修剪会更有效。通常,聚合树的所有分支都在一次深度优先传递中展开,然后才会发生任何修剪。在某些情况下,这可能非常浪费,并且可能会遇到内存限制。

基本原理即:推迟子聚合的计算

4.2 原理

4.3 适用场景及基本用法

4.3.1 用法:Collect mode

"collect_mode": "{collect_mode.value}" 

4.3.2 参数

  • breadth_first:广度优先模式属于最上层桶的一组文档被缓存以备后续重播,因此执行此操作时内存开销与匹配文档的数量成线性关系。即:先做第一层聚合,逐层修剪。
  • depth_first:即:先构建完整的树,然后修剪无用节点。

4.4 注意

广度优先仅仅适用于每个组的聚合数量远远小于当前总组数的情况下,因为广度优先会在内存中缓存裁剪后的仅仅需要缓存的每个组的所有数据,以便于它的子聚合分组查询可以复用上级聚合的数据。

广度优先的内存使用情况与裁剪后的缓存分组数据量是成线性的。对于很多聚合来说,每个桶内的文档数量是相当大的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/692845.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IT闲谈-Kylin入门教程

目录 一、引言二、Kylin简介三、环境准备四、安装与配置五、数据导入与建模六、查询与分析七、总结 一、引言 Apache Kylin是一个开源的分布式分析引擎&#xff0c;旨在提供Hadoop/Spark之上的SQL接口及多维分析&#xff08;OLAP&#xff09;能力以支持超大规模数据。Kylin通过…

计算机毕业设计项目、管理系统、可视化大屏、大数据分析、协同过滤、推荐系统、SSM、SpringBoot、Spring、Mybatis、小程序项目编号1-500

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

设计模式-工厂方法(创建型)

创建型-工厂方法 简单工厂 将被创建的对象称为“产品”&#xff0c;将生产“产品”对象称为“工厂”&#xff1b;如果创建的产品不多&#xff0c;且不需要生产新的产品&#xff0c;那么只需要一个工厂就可以&#xff0c;这种模式叫做“简单工厂”&#xff0c;它不属于23中设计…

樱花动漫2024最新网页地址链接

大家好&#xff01;今天我要为大家种草一个非常棒的动漫资源在线平台——樱花动漫网页。作为一个网络文化研究者&#xff0c;我一直在关注当代动漫文化的发展和传播方式。而樱花动漫网页正是我近期发现的一颗璀璨明珠&#xff0c;它不仅为动漫爱好者提供了一个交流、分享的平台…

2.数人数

上海市计算机学会竞赛平台 | YACSYACS 是由上海市计算机学会于2019年发起的活动,旨在激发青少年对学习人工智能与算法设计的热情与兴趣,提升青少年科学素养,引导青少年投身创新发现和科研实践活动。https://www.iai.sh.cn/problem/431 题目描述 在一个班级里,男生比女生多…

mysql 更改数据存储目录

先停止 mysql &#xff1a;sudo systemctl start/stop mysql 新建新的目录&#xff0c; 比如 /mnt/data/systemdata/mysql/mysql_data sudo chown -R mysql:mysql /mnt/data/sysdata/mysql/mysql_data sudo chmod -R 750 /mnt/data/sysdata/mysql/mysql_data 更改mysql.cnf…

【设计模式】行为型设计模式之 职责链模式,探究过滤器、拦截器、Mybatis插件的底层原理

一、介绍 职责链模式在开发场景中经常被用到&#xff0c;例如框架的过滤器、拦截器、还有 Netty 的编解码器等都是典型的职责链模式的应用。 标准定义 GOF 定义&#xff1a;将请求的发送和接收解耦&#xff0c;让多个接收对象都有机会处理这个请求&#xff0c;将这些接收对象…

联合体和枚举类型

1.联合体 1.1 联合体类型的声明 像结构体⼀样&#xff0c;联合体也是由⼀个或者多个成员构成&#xff0c;这些成员可以不同的类型。 但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同⼀块内存空间。所以联合体也叫&#xff1a;共用体。 给联合体…

数据并非都是正态分布:三种常见的统计分布及其应用

你有没有过这样的经历&#xff1f;使用一款减肥app&#xff0c;通过它的图表来监控自己的体重变化&#xff0c;并预测何时能达到理想体重。这款app预测我需要八年时间才能恢复到大学时的体重&#xff0c;这种不切实际的预测是因为应用使用了简单的线性模型来进行体重预测。这个…

C++ list链表的使用和简单模拟实现

目录 前言 1. list的简介 2.list讲解和模拟实现 2.1 默认构造函数和push_back函数 2.2 迭代器实现 2.2.1 非const正向迭代器 2.2.2 const正向迭代器 2.2.3 反向迭代器 2.3 插入删除函数 2.3.1 insert和erase 2.3.2 push_back pop_back push_front pop_front 2.4 构…

LLVM Cpu0 新后端3

想好好熟悉一下llvm开发一个新后端都要干什么&#xff0c;于是参考了老师的系列文章&#xff1a; LLVM 后端实践笔记 代码在这里&#xff08;还没来得及准备&#xff0c;先用网盘暂存一下&#xff09;&#xff1a; 链接: https://pan.baidu.com/s/1V_tZkt9uvxo5bnUufhMQ_Q?…

173.二叉树:找树左下角的值(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr, right(nullptr) {}* Tree…

强!推荐一款开源接口自动化测试平台:AutoMeter-API !

在当今软件开发的快速迭代中&#xff0c;接口自动化测试已成为确保代码质量和服务稳定性的关键步骤。 随着微服务架构和分布式系统的广泛应用&#xff0c;对接口自动化测试平台的需求也日益增长。 今天&#xff0c;我将为大家推荐一款强大的开源接口自动化测试平台: AutoMete…

【中国开源生态再添一员】天工AI开源自家的Skywork

刚刚看到《AI高考作文出圈&#xff0c;网友票选天工AI居首》&#xff0c;没想到在Huggingface中发现了Skywork大模型。天工大模型由昆仑万维自研&#xff0c;是国内首个对标ChatGPT的双千亿级大语言模型&#xff0c;天工大模型通过自然语言与用户进行问答式交互&#xff0c;AI生…

用c语言实现通讯录

目录 静态简易通讯录 代码&#xff1a; 功能模块展示&#xff1a; 设计思路&#xff1a; 动态简易通讯录&#xff08;本质顺序表&#xff09; 代码&#xff1a; 扩容模块展示&#xff1a; 设计思路&#xff1a; 文件版本通讯录 代码&#xff1a; 文件模块展示&#x…

突破网络屏障:掌握FRP内网穿透技术

1.FRP介绍 1.frp是什么 frp 是一款高性能的反向代理应用&#xff0c;专注于内网穿透。它支持多种协议&#xff0c;包括 TCP、UDP、HTTP、HTTPS 等&#xff0c;并且具备 P2P 通信功能。使用 frp&#xff0c;您可以安全、便捷地将内网服务暴露到公网&#xff0c;通过拥有公网 I…

【C++ STL】模拟实现 string

标题&#xff1a;【C :: STL】手撕 STL _string 水墨不写bug &#xff08;图片来源于网络&#xff09; C标准模板库&#xff08;STL&#xff09;中的string是一个可变长的字符序列&#xff0c;它提供了一系列操作字符串的方法和功能。 本篇文章&#xff0c;我们将模拟实现STL的…

【机器学习】消息传递神经网络(MPNN)在分子预测领域的医学应用

1. 引言 1.1. 分子性质预测概述 分子性质预测是计算机辅助药物发现流程中至关重要的任务之一&#xff0c;它在许多下游应用如药物筛选和药物设计中发挥着核心作用&#xff1a; 1.1.1. 目的与重要性&#xff1a; 分子性质预测旨在通过分子内部信息&#xff08;如原子坐标、原…

汇总 |国内外医疗器械网络安全法规与标准

国内外关于医疗器械网络安全的法规和标准日益完善&#xff0c;旨在确保医疗器械在全生命周期内的网络安全&#xff0c;保障患者信息的安全和隐私&#xff0c;以及医疗器械的正常运行。不同国家和地区的法规和标准各有侧重&#xff0c;但都强调了医疗器械制造商、开发者、经营者…

contos7使用docker安装vulhub

contos7下使用docker安装vulhub 1. 安装docker 1. 更新yum &#xff08;1&#xff09;切换root用户 su root &#xff08;2&#xff09;更新yum yum update 2. 卸载旧版本的docker sudo yum remove docker sudo yum remove docker-client sudo yum remove docker-clien…