6.ELK之Elasticsearch嵌套(Nested)类型
0、前言
在Elasticsearch实际应用中经常会遇到嵌套文档的情况,而且会有“对象数组彼此独立地进行索引和查询的诉求”。在ES中这种嵌套文档称为父子文档,父子文档“彼此独立地进行查询”至少有以下两种方式:
1)父子文档。在ES的5.x版本中通过parent-child父子type实现,即一个索引对应多个type;
对于6.X+版本由于不再支持一个索引多个type,所以父子索引的实现改成了Join。
2)Nested嵌套类型。
1、ES数据类型概览
1.常见类型
binary:接受二进制值作为 Base64 编码的字符串。默认情况下,该字段不存储,也不可搜索,不能包含换行符 \n
boolean:布尔类型,可以接受 true 或 false ,可以使用字符串和直接到布尔类型,空字符串为 false,包含:true,false,"true","false",""
keyword:关键字类型,不进行分词,直接索引,支持模糊、支持精确匹配,支持聚合、排序操作,用于筛选数据。最大支持的长度为——32766 个 UTF-8 类型的字符。
number:数字类型,文档链接
long
integer
short
byte
double
float
half_float
scaled_float
unsigned_longDates:日期类型
date:可以是格式化后的日期字符串,也可以是时间戳,例如 2015-01-01, 2015-01-01T12:10:30Z,1420070400001
date_nanos:支持纳秒的日期格式,在 es 内部是存的长整型
alias :别名类型2.对象和关系类型
object:对象类型,是一个 json 对象
flattened:将对象作为单个字段值存储
nested:嵌套数据类型,可以看成是一个特殊的对象类型,可以让对象数组独立检索
join:同一个文档,但具有父子关系的,类似于树
3.结构化数据类型
range:范围类型,可以用来表示数据的区间
integer_range
float_range
long_range
double_range
date_range
ip_range
2、一个例子说明nested类型的作用
(1)Nested:嵌套对象是object数据类型的专用版本,能够对 对象数组进行彼此独立地索引和查询。
(2)对象数组默认组织形式
内部对象字段数组的实际存储机制与我们想的不一样。Lucene没有内部对象的概念,因为ElasticSearch将对象层次结构扁平化为一个字段名和字段值的列表。例如下面文档。
PUT user/user_info/1
{"group" : "man","userName" : [ {"first" : "张","last" : "三"},{"first" : "李","last" : "四"}]
}
这里想要查询first为“张”,last为“四”的数据,按照我们的理解应该没有这种数据。按如下语句查询。
PUT user/user_info/1
{"group" : "human","sex": "man","userName" : [ {"first" : "张","last" : "三"},{"first" : "李","last" : "四"}]
}
查询结果如下:居然查询到了。这显然不符合我们的预期。
这个原因就是前面所说的lucene没有内部对象的概念,所谓的内部对象实际是被扁平化为一个简单的字段名称和值列表。文档内部存储是这个样子的:
{"group" : "human","sex" : "man","userName.first" : [ "张", "李" ],"userName.last" : [ "三", "四" ]
}
显然 userName.first 和 userName.last 字段平面化为多值字段,之前的关联性丢失,查询就不会得到预期的结果。
那么要如何实现自己想要的语义呢? —— 显然就是本文想要说的nested了。
3、nested类型的使用
3.1、首先插入如下一条记录
其含义为博客文章信息数据,其中每篇文章的评论以comments字段数组存储。
PUT /financeblogs/blog/docidart1
{"title": "Invest Money","body": "Please start investing money as soon...","tags": ["money", "invest"],"published_on": "18 Oct 2017","comments": [{"name": "William","age": 34,"rating": 8,"comment": "Nice article..","commented_on": "30 Nov 2017"},{"name": "John","age": 38,"rating": 9,"comment": "I started investing after reading this.","commented_on": "25 Nov 2017"},{"name": "Smith","age": 33,"rating": 7,"comment": "Very good post","commented_on": "20 Nov 2017"}]
}
现在对于这条数据评论人姓名、年龄如下。
name | age |
---|---|
William | 34 |
John | 38 |
Smith | 33 |
3.2、非nested时内部对象无法按预期查询
我们尝试查询{name:John, age:34}评论过的博客,按照我们的理解应该没有符合条件的记录。但是由于前面说过的平铺的原因实际上如下查询语句是检索到这条数据了的。
GET /financeblogs/blog/_search
{"query":{"bool":{"must":[{"match":{"comments.name":"John"}},{"match":{"comments.age":"34"}}]}}
}
3.3、接下来换成nested的玩法
0.把这个索引删除再来一遍
DELETE financeblogs
1.创建如下索引。主要是mapping中的comments字段指定了类型为 nested。
PUT /financeblogs
{"mappings": {"blog": {"properties": {"title": {"type": "text"},"body": {"type": "text"},"tags": {"type": "keyword"},"published_on": {"type": "keyword"},"comments": {"type": "nested","properties": {"name": {"type": "text"},"comment": {"type": "text"},"age": {"type": "short"},"rating": {"type": "short"},"commented_on": {"type": "text"}}}}}}
}
2.插入同样的目标数据
PUT /financeblogs/blog/docidart1
{"title": "Invest Money","body": "Please start investing money as soon...","tags": ["money", "invest"],"published_on": "18 Oct 2017","comments": [{"name": "William","age": 34,"rating": 8,"comment": "Nice article..","commented_on": "30 Nov 2017"},{"name": "John","age": 38,"rating": 9,"comment": "I started investing after reading this.","commented_on": "25 Nov 2017"},{"name": "Smith","age": 33,"rating": 7,"comment": "Very good post","commented_on": "20 Nov 2017"}]
}
3.使用nested查询方法
#查询name为John,age为34的记录发现是没有数据的。GET /financeblogs/blog/_search?pretty
{"query": {"bool": {"must": [{"nested": {"path": "comments","query": {"bool": {"must": [{"match": {"comments.name": "John"}},{"match": {"comments.age": 34}}]}}}}]}}
}
4.查询name为John,age为38的数据就是有的
4、父子和嵌套两种方式比对
项 | 嵌套(nested) | 父子文档 |
优点 | 读取性能高 (据官方:比父子快5~10倍) | 父子文档可以独立更新 |
缺点 | 更新子文档时需要更新整个文档 | 读取性能差,CPU占用率高 (需额外的内存去维护关系) |
适应场景 | 查询为主,子文档偶尔更新的场景 | 子文档频繁更新; 子文档经常查询。 |
嵌套文档看似只是文档内有一个集合字段,但内部存储完全不是。以下图嵌套文档为例;留言1,留言2,留言3在内部实际存储为4个独立文档。
同时,嵌套文档的字段类型需要设置为nested。设置成nested后就不能被直接查询了,需要使用nested查询。
总结来说:
1.普通子对象默认实现了一对多的关系,会损失子对象的边界,子对象属性的关联性也会丧失。
2.嵌套(nested)对象可以解决普通子对象存在的问题,但是它有两个缺点:一是更新文档的时候要全部更新,另外就是不支持子文档从属多个主文档的场景。
3.父子文档能解决前面两个存在的问题,但是它适用于写多读少的场景(查询效率较慢)。
关于nested更多其他语法,参见:
干货 | Elasticsearch Nested类型深入详解_es nest类型-CSDN博客
相关文章:

6.ELK之Elasticsearch嵌套(Nested)类型
0、前言 在Elasticsearch实际应用中经常会遇到嵌套文档的情况,而且会有“对象数组彼此独立地进行索引和查询的诉求”。在ES中这种嵌套文档称为父子文档,父子文档“彼此独立地进行查询”至少有以下两种方式: 1)父子文档。在ES的5.…...

RefConv: 重参数化的重新聚焦卷积(论文翻译)
文章目录 摘要1、简介2、相关研究2.1、用于更好性能的架构设计2.2、结构重参数化2.3、权重重参数化方法 3、重参数化的重聚焦卷积3.1、深度RefConv3.2、普通的RefConv3.3、重聚焦学习 4、实验4.1、在ImageNet上的性能评估4.2、与其他重参数化方法的比较4.3、目标检测和语义分割…...

指令重排序
指令重排序是现代处理器在执行指令时的一种优化技术,其目的是为了提高处理器执行指令的效率。这种优化手段会对指令进行重新排序,以提高并行度和性能。 为何会发生指令重排序: 处理器性能优化: 为了更好地利用现代处理器的流水线、…...

【Head First 设计模式】-- 观察者模式
背景 客户有一个WeatherData对象,负责追踪温度、湿度和气压等数据。现在客户给我们提了个需求,让我们利用WeatherData对象取得数据,并更新三个布告板:目前状况、气象统计和天气预报。 WeatherData对象提供了4个接口: …...

JavaWeb篇_01——JavaEE简介【面试常问】
JavaEE简介 什么是JavaEE JavaEE(Java Enterprise Edition),Java企业版,是一个用于企业级web开发平台,它是一组Specification。最早由Sun公司定制并发布,后由Oracle负责维护。在JavaEE平台规范了在开发企业级web应用…...

QtC++与QRadioButton详解
介绍 QRadioButton 是 Qt 中的一个重要部件,用于创建单选按钮,它有以下几个主要作用和特点: 单选功能: QRadioButton 用于创建单选按钮,用户可以从一组互斥的选项中选择一个。这在用户界面设计中常用于需要用户从多个…...

移远EC600U-CN开发板 day01
1.官方文档快速上手,安装驱动,下载QPYcom QuecPython 快速入门 - QuecPython (quectel.com)https://python.quectel.com/doc/Getting_started/zh/index.html 注意: (1)打开开发板步骤 成功打开之后就可以连接开发板…...

【C/C++】什么是POD(Plain Old Data)类型
2023年11月6日,周一下午 目录 POD类型的定义标量类型POD类型的特点POD类型的例子整数类型:C 风格的结构体:数组:C 风格的字符串:std::array:使用 memcpy 对 POD 类型进行复制把POD类型存储到文件中,并从文…...

注册虾皮买家号需要哪些资料?
注册虾皮买家号其实是很简单的,使用相应国家的手机号及对应的环境就可以注册了的,如果想要账号更方便使用,也可以绑定邮箱进行认证。 而如果想要使用shopee买家通系统进行自动化的注册,那么对于资料就有一定的要求了。 1、手机号…...

小腿筋膜炎怎么治疗最有效
小腿筋膜炎症状主要有疼痛、肌肉紧张、活动受限等。 1.疼痛:小腿筋膜炎主要会导致炎症性疼痛,没有固定的压痛点,通常以踝关节、膝关节活动时疼痛为主。疼痛呈持续性,或者反复发作,尤其是在晨起或者天气变化、劳累、受…...

After Effects 2024 v24.0.2(AE2024)
After Effects 2024是视频特效和动态图形设计软件。以下是After Effects 2024的主要功能和特点: 支持创建各种令人惊叹的视觉效果,例如粒子系统、合成特效、绿屏抠像等。支持动画制作,包括关键帧动画、形状动画、运动跟踪等工具,…...

自己实现一个自动检测网卡状态,并设置ip地址
阅读本文前,请先学习下面几篇文章 《搞懂进程组、会话、控制终端关系,才能明白守护进程干嘛的?》 《简简单单教你如何用C语言列举当前所有网口!》 《Linux下C语言操作网卡的几个代码实例!特别实用》 《安卓如何设置…...

【Linux】进程程序替换
文章目录 替换原理站在进程的角度站在程序的角度初体验及理解原理 替换函数函数解释命名理解exec系列函数与main函数之间的关系在一个程序中调用我们自己写的程序 替换原理 创建子进程的目的是什么? ->想让子进程执行父进程代码的一部分 执行父进程对应的磁盘代码…...

项目构建工具maven的基本配置+idea 中配置 maven
👑 博主简介:知名开发工程师 👣 出没地点:北京 💊 2023年目标:成为一个大佬 ——————————————————————————————————————————— 版权声明:本文为原创文…...

【解密ChatGPT】:从过去到未来,揭示其发展与变革
🎊专栏【ChatGPT】 🌺每日一句:天行健,君子以自强不息,地势坤,君子以厚德载物 ⭐欢迎并且感谢大家指出我的问题 文章目录 一、ChatGPT的发展历程 二、ChatGPT的技术原理 三、ChatGPT的应用场景 四、ChatGPT的未来趋势 五、总结 引言:随着…...

系统架构设计】计算机公共基础知识: 5 数学与经济管理
一 运筹方法 1 线性规划 线性规划问题的数学模型通常由线性目标函数、线性约束条件、变量非负条件组成,特点如下: (1)线性规划的可行解域是由一组线性约束条件形成的。 (2)如果存在两个最优解,则连接这两点的线段内所有的点都是最优解,而线段两端延长线上可能会超出…...

Visual Studio 2019光标变成灰色方块问题
文章目录 Visual Studio 2019光标变成灰色方块问题问题描述解决方案 Visual Studio 2019光标变成灰色方块问题 问题描述 单击和双击都无法选中单词,总是选择整行或者是当前光标处的前几个字符一起选中,没有规则,貌似选择单词复制࿰…...

C++ http协议POST body raw 字段向服务器发送请求
环境:ubuntu系统c使用http协议不是很方便,通过curl库我们可以很方便使用http协议,由于我的请求方式比较特殊,在网上没有找到相关的资料,之前使用python实现过一版,但是当设备数量超过100台时,程…...

通过migrate命令实现两个redis实例之间的数据迁移
本文适用于将源服务器的redis实例的key的数据迁移到其他服务器的redis实例 一、migrate简介: migrate用于在Redis实例间进行数据迁移,实际上migrate命令是将dump、restore、del三个命令进行组合,从而简化了操作流程。migrate命令具有原子性&…...

Unity 判断两个UI是否相交
今天碰到要判断两个UI是否相交的交互。 尝试了下,发现有两个方法都成功了。 1、使用Collider2D组件 分别创建两个Image组件,并且添加Collider2D组件,其中一个还要添加Rigidbody2D组件,如下图: 然后创建个判断脚本“…...

swoole process 消息通信
swoole文档:Swoole 文档 process子进程和父进程之间通信,依靠监听。子进程和父进程分别做监听。父进程写入信息,子进程监听接收。子进程向父进程写入,调用父进程监听。 子进程向父进程写入信息有两种方式,一种调用wr…...

uniapp跳转方式
UniApp 是一个基于 Vue.js 的跨平台开发框架,可以同时构建 iOS、Android、H5 和小程序等多个平台的应用。在 UniApp 中,我们可以使用以下几种方式进行页面之间的跳转: 使用 uni.navigateTo 方法:该方法可以在当前页面打开新的页面…...

六大排序算法:插入、选择、冒泡、快排、希尔、归并
1、插入排序 解析:第一个元素设定为已经排好序,依次选择后续的元素插入到已经排好序的组内进行排序。 图示: 代码: public static void insertionSort(int[] arr) {int n arr.length;for (int i 1; i < n; i) {int key a…...

短信登录实现(黑马点评为例)
文章目录 前言一、隐藏用户敏感信息二、短信验证登录、注册1.流程2.代码3.使用redis优化解决代码 二、登录拦截(校验)1.流程2.代码 总结 前言 短信登录核心知识 首先黑马点评这个短信登录是一伪验证,即后台调用工具类随机生成六位数字。 1.R…...

【uniapp】签名组件,兼容vue2vue3
网上找了个源码改吧改吧,清除了没用的功能和兼容性,基于uniapp开发的 样子 vue2 使用方法,具体的可以根据业务自行修改 <signature ref"signature" width"100%" height"410rpx"></signature>confi…...

初步利用Ansible实现批量服务器自动化管理
1.Ansible介绍 Ansible是一款开源的自动化运维工具, 在2012年由Michael DeHaan创建, 现在由Red Hat维护。Ansible是基于Python开发的,采用YAML语言编写自动化脚本playbook, 可以在Linux、Unix等系统上运行, 通过SSH协议管理节点, 无需在被管理节点安装agent。Ansible以其简单、…...

网络安全和隐私保护技术
一、定义 网络安全和隐私保护技术是指在互联网和其他网络环境中,通过技术手段保护网络系统、网络数据和用户隐私免于受到恶意攻击、非法访问、窃取或滥用。网络安全和隐私保护技术是保护网络安全和用户隐私的重要手段,是保障互联网和其他网络环境正常运…...

保险行业采购管理痛点及解决方案(数智化采购系统)
随着社会发展,个人和企业有了更多的金融保险需求。对于金融保险公司而言,需要在采购合规的基础上,基于数智化能力,让经营变得更加高效和智能。 1、围绕重点领域,业务加速布局。 保险行业结合自身业务经营重点&#x…...

光学仿真 | 仿真推动以人类视觉感知为本的汽车显示设计
如果产品设计无法使终端用户产生共鸣,就不会存在卓越的工程设计。您可以设计一种结构坚固的方向盘,但如果它被放在错误的位置,就无法实现其用于转向的主要目的。 同样,在围绕人类视觉进行设计时,显示器其实无需具备尽…...

判断两个对象是否不相等operator.ne()
【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 判断两个对象是否不相等 operator.ne() 选择题 下列代码执行输出的结果是? import operator print("【执行】operator.ne(8,8)") print(operator.ne(8,8)) print("【执行】…...