一. ES parent-child 文档简介

ES 提供了类似数据库中 Join 联结的实现,可以通过 Join 类型的字段维护父子关系的数据,其父文档和子文档可以单独维护。

二. 父子文档的索引创建与数据插入

ES 父子文档的创建可以分为下面三步:

  • 创建索引 Mapping,指明数据类型为 join 与父子文档名
  • 插入父文档
  • 插入子文档

下面针对每一步做演示。

1. 创建索引

假设我们有一个博客系统,每篇博客下有若干条评论,那么博客 blog 与评论 comment 就构成了一个父子关系。

父子文档的创建方为:

  • 指定字段类型为 join
  • 通过 relations 指定父子关系

示例如下:

# blog 为父文档,comment 为子文档
PUT blog_index
{"mappings": {"properties": {"blog_comment_join": {"type": "join","relations": {"blog": "comment"}}}}
}
2. 插入父文档
PUT blog_index/_doc/1
{"title": "First Blog","author": "Ahri","content": "This is my first blog","blog_comment_join": {"name": "blog"}
}PUT blog_index/_doc/2
{"title": "Second Blog","author": "EZ","content": "This is my second blog","blog_comment_join": "blog"
}
3. 插入子文档

插入子文档时需要注意一点:

  • routing 设置:子文档必须要与父文档存储在同一分片上,因此子文档的 routing 应该设置为父文档 ID 或者与父文档保持一致

示例代码如下:

PUT blog_index/_doc/comment-1?routing=1&refresh
{"user": "Tom","content": "Good blog","comment_date": "2020-01-01 10:00:00","blog_comment_join": {"name": "comment","parent": 1}
}PUT blog_index/_doc/comment-2?routing=1&refresh
{"user": "Jhon","content": "Good Job","comment_date": "2020-02-01 10:00:00","blog_comment_join": {"name": "comment","parent": 1}
}PUT blog_index/_doc/comment-3?routing=2&refresh
{"user": "Jack","content": "Great job","comment_date": "2020-01-01 10:00:00","blog_comment_join": {"name": "comment","parent": 2}
}
4. 其他

除了上面常见的父子文档类型,ES Join 还支持 多子文档多级父子文档 的设置。如下:

构建多个子文档

Join 类型一个父文档可以配置多个子文档,创建方式如下:

PUT my_index
{"mappings": {"properties": {"my_join_field": {"type": "join","relations": {"question": ["answer", "comment"]  }}}}
}

构建多级父子关系

PUT my_index
{"mappings": {"properties": {"my_join_field": {"type": "join","relations": {"question": ["answer", "comment"],  "answer": "vote" }}}}
}

上面创建的父子文档层级如下图所示:

在这里插入图片描述

三. 父子文档的查询

基于父子文档的查询主要有三种:

  • parent_id:基于父文档 ID 查询所有的子文档
  • has_parent:查询符合条件的父文档的所有子文档
  • has_child:查询符合条件的子文档的所有父文档

下面是具体查询示例:

【1】parent_id 查询
# 查询 ID1 父文档的所有子文档
GET blog_index_parent_child/_search
{"query": {"parent_id": {"type": "comment","id": 1}}
}# 结果返回
{"took" : 1,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.44183275,"hits" : [{"_index" : "blog_index","_type" : "_doc","_id" : "comment-1","_score" : 0.44183275,"_routing" : "1","_source" : {"user" : "Tom","content" : "Good blog","comment_date" : "2020-01-01 10:00:00","blog_comment_join" : {"name" : "comment","parent" : 1}}},{"_index" : "blog_index","_type" : "_doc","_id" : "comment-2","_score" : 0.44183275,"_routing" : "1","_source" : {"user" : "Jhon","content" : "Good Job","comment_date" : "2020-02-01 10:00:00","blog_comment_join" : {"name" : "comment","parent" : 1}}}]}
}
【2】has_parent 查询
# 查询 title 包含 first 的父文档的所有子文档
GET blog_index/_search
{"query": {"has_parent": {"parent_type": "blog","query": {"match": {"title": "first"}}}}
}
# 结果返回
{"took" : 1,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "blog_index","_type" : "_doc","_id" : "comment-1","_score" : 1.0,"_routing" : "1","_source" : {"user" : "Tom","content" : "Good blog","comment_date" : "2020-01-01 10:00:00","blog_comment_join" : {"name" : "comment","parent" : 1}}},{"_index" : "blog_index","_type" : "_doc","_id" : "comment-2","_score" : 1.0,"_routing" : "1","_source" : {"user" : "Jhon","content" : "Good Job","comment_date" : "2020-02-01 10:00:00","blog_comment_join" : {"name" : "comment","parent" : 1}}}]}
}
【3】has_child 查询
# 查询 user 包含 Jack 的所有子文档的父文档
GET blog_index/_search
{"query": {"has_child": {"type": "comment","query": {"match": {"user": "Jack"}}}}
}
# 结果返回
{"took" : 1,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "blog_index","_type" : "_doc","_id" : "2","_score" : 1.0,"_source" : {"title" : "Second Blog","author" : "EZ","content" : "This is my second blog","blog_comment_join" : "blog"}}]}
}

四. Nested 对象 VS 父子文档

下面是极客时间课程《Elasticsearch核心技术与实战》中给出的对比:

在这里插入图片描述

一般来说大多数数据还是读多写少的,因此大多数时候还是优先使用 Nested 对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93276.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93276.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/93276.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】编辑器vim的使用

目录 1. vim的基本概念 2. vim的基本使用 3. vim命令模式操作 3.1 移动光标 3.2 删除 3.3 复制 3.4 替换 3.5 撤销 3.6 更改 3.7 跳转 4. vim底行模式操作 4.1 列出行号 4.2 跳到文件中的某行 4.3 查找字符 4.4 保存文件 4.5 离开vim 1. vim的基本概念 Vim&…

《零基础掌握飞算Java AI:核心概念与案例解析》

前引:飞算科技是一家专注于企业级智能化技术服务的公司,核心领域包括AI、大数据、云计算等。其Java AI解决方案主要面向企业级应用开发,提供从数据处理到模型部署的全流程支持!飞算Java AI是一款基于人工智能技术的Java开发辅助工…

Chrome腾讯翻译插件transmart的安装

文章目录一、官网地址二、安装过程1. 下载插件2. 解压crx3, chrome安装三、如何使用一、官网地址 腾讯翻译插件官网 二、安装过程 1. 下载插件 点击上面的官网地址,下拉到如图所示chrome插件位置,点击立即下载 2. 解压crx 从压缩文件中解压出crx文…

IOMMU的2级地址翻译机制及多级(2~5)页表查找

IOMMU的2级地址翻译机制及多级(2~5)页表查找 摘要:IOMMU是现代计算机系统中用于I/O设备(如GPU、NIC、网络接口卡)的地址翻译和保护机制,类似于CPU的MMU(Memory Management Unit),但专为设备DMA(Direct Memory Access,直接内存访问)设计。它支持虚拟化环境(…

C++STL标准模板库详解

一、引言STL(Standard Template Library)是 C 标准库的核心组成部分,其中容器(Containers) 作为数据存储的基础组件,为开发者提供了丰富的数据结构选择。本文将聚焦 STL 容器的核心类型,结合具体…

神经网络 常见分类

📚 神经网络的常见分类方式可以从不同角度来划分,以下是几种主流思路,帮你快速梳理清晰:1️⃣ 按网络结构分类前馈神经网络(Feedforward Neural Network, FNN) 数据从输入层→隐藏层→输出层单向传递&#…

生产环境Redis缓存穿透与雪崩防护性能优化实战指南

生产环境Redis缓存穿透与雪崩防护性能优化实战指南 在当下高并发场景下,Redis 作为主流缓存组件,能够极大地提升读写性能,但同时也容易引发缓存穿透、缓存击穿及缓存雪崩等问题,导致后端依赖数据库的请求激增,系统稳定…

【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)

🔥个人主页:艾莉丝努力练剑 ❄专栏传送门:《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题、洛谷刷题、C/C基础知识知识强化补充、C/C干货分享&学习过程记录 🍉学习方向:C/C方向 ⭐️人…

嵌入式硬件篇---常见的单片机型号

以下是目前常用的单片机型号及其应用场景、优劣势的详细解析,结合最新行业动态和技术特性,帮助你精准匹配需求:一、经典 8 位单片机:低成本入门首选1. 51 系列(代表型号:AT89C51、STC89C52)应用…

windows下ArcGIS 10.8.2下载安装教程

ArcGIS是由美国环境系统研究所(Esri)开发的一款功能强大且应用广泛的综合性地理信息系统(GIS)软件平台,在空间数据的采集、管理、分析、可视化和共享等方面表现出色,是GIS领域的标杆产品。它拥有丰富的功能…

防御保护15

混合密码体系 --- 数字信封 逻辑 --- 先用快速的对称密钥来对消息进行加密,保证数据的机密性。然后只需要保证对称密钥的机密性即可,使用公钥密钥体系来对对称秘钥消息进行加密。身份认证和数据认证技术 Hash散列 指纹 ---> 单向散列函数 Hash --->…

Linux上管理Java的JDK版本

1.alternatives简介alternatives是 Linux 系统(尤其是 ​​RHEL/CentOS/Fedora​​ 等基于 RPM 的发行版)中用于管理​​同一软件多个版本​​的系统工具。它通过维护符号链接(软链接)的层级结构,帮助用户在不冲突的情…

webrtc编译arm/arm64

webrtc版本 m125版本 编译arm sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf //下载失败,需要多次尝试 python3 build/linux/sysroot_scripts/install-sysroot.py --arch=arm //python3 bui

【读论文】医疗AI大模型:百川开源Baichuan-M2

1. 引言 最新百川开源了一个可以和openai新模型掰手腕的医疗垂直大模型:Baichuan-M2在HealthBench基准上取值60.1的高分,超过了gpt-oss-120b。这次一起回顾下百川给的技术报告。 2. Baichuan-M2概览:“模型+系统” Baichuan-M2的成功源于一套精心设计的、端到端的训练与优…

OBOO鸥柏丨75寸/86平板企业办公会议触控一体机核心国产化品牌招投标参数

OBOO鸥柏整机参数要求:55寸/65寸/75寸/85-86寸/98寸/100寸/110寸/115寸智能会议平板教学触控一体机/智慧黑板触摸屏参数要求。系统可灵活选择如:支持安卓(Android),Windows可选择。并在KylinOS银河麒麟操作系统、统信U…

DCT域信息隐藏中超参数影响的深度解析:从理论到实践的完整指南

摘要 随着数字媒体技术的飞速发展,信息隐藏技术在版权保护、内容认证和隐私保护等领域发挥着越来越重要的作用。离散余弦变换(DCT)域作为信息隐藏的经典载体,因其与JPEG压缩标准的天然兼容性而备受关注。然而,DCT域信息隐藏的效果很大程度上取决于各种超参数的精心调节,…

YOLOv8环境配置命令

【YOLOv8】一小时掌握,从0开始搭建部署YOLOv8系列教程,安装推理自定义数据集训练与搭建_哔哩哔哩_bilibili【YOLOv8】一小时掌握,从0开始搭建部署YOLOv8系列教程,安装推理自定义数据集训练与搭建共计10条视频,包括&…

Maven私服配置模版

参考课程: 【黑马程序员 JavaWeb开发教程】 [https://www.bilibili.com/video/BV1m84y1w7Tb] ZZHow(ZZHow1024)Maven 的 settings.xml 配置文件中(从私服下载项目到本地) 在 servers 标签中,配置访问私服的个人凭证(访问的用户名和…

《智能体(Agent)速记指南》

《智能体(Agent)速记指南》 📘 一句话核心:智能体 会判断 会用工具,能独立完成任务的系统。一、智能体到底是什么? ✅ 一句话定义:能独立跑完一个完整任务,不用人盯着。 ⚠️ 别搞…

BERT模型引入及详解

BERT模型引入及详解 参考 视频: ELMo 模型(双向 LSTM 模型解决词向量多义问题 博客: BERT模型BERT详解:概念、原理与应用一文读懂BERT ELMo模型 参考: 视频: ELMo模型(双向LSTM模型解决词向量多义问题) 博客: 【…