ES入门十:关系模型的实现:嵌套类型和父子文档

现实中,关系模型是到处存在的,例如书本与作者的关系。但是在ES中想要处理这个事情并不简单

在ES中保存关系型模型数据的方式主要有以下几种:

  • nested:在这种方式中,会通过一对多的放系保存在同一个文档中
  • join(parent/child):通过维护文档的父子节点,将两个对象分离

上面这2种方式都可以描述一对多的关系,今天我们就来了解一下

nested(嵌套类型)

nested类型是一种特别的object类型,其允许数组中的对象可以被单独索引,使他们可以被独立地索引。下面的示例是使用普通的object数组来保存书本与作者的一对多关系,我们看看会产生什么问题

# 创建 Mapping
PUT books_index
{"mappings": {"properties": { "book_id": { "type": "keyword" },"author": { "properties": {"first_name": { "type": "keyword" },"last_name": { "type": "keyword" }}}}}
}# 写入书本数据
PUT books_index/_doc/1
{"book_id": "1234","author": [{ "first_name": "zhang", "last_name": "san" },{ "first_name": "wang", "last_name": "wu" }]
}

如上面的示例,我们创建了books_index索引,其中author字段是一个对象,包括了first_name与last_name两个属性,并且在我们写入数据的时候,书本的作者有两个(描述了一对多的关系):zhangsan和wangwu。

我们对上面的数据进行一个查询:
image.png
image.png
按道理来说我们的数据中是没有zhangwu这个作者的,但是在实际查询中能命中文档1,为什么那?
因为object被扁平化指挥,其丢失了first_name和last_name之间的关系,变成了下面这样的关系
image.png
对于这个扁平化的数组,原先first_name和last_name见的关系当然以及不复存在了。所以我们的查询语句在author.first_name中匹配了“zhang”,在author.last_name匹配了“wu”,自然就命中了文档1,那么有什么办法解决这个问题吗?
那就是使用nested数据类型,他可以是对象数组的对象被独立索引,这样fist_name和last_name之间的关系就不会丢失了。下面我们修改一下mapping,把author的类型定义为nested:
image.png
如上所示,使用nested关键字指定一个nested对象的查询,使用path指定nested对象的名字。

从上面的示例来看,nested通过冗余的方式将对象和文档存储在一起,所以查询时的性能是很高的,但是需要更新对象的时候,需要更新所有包含此对象的文档,例如某个作者的信息更改了,那么所有这个作者的书本文档都需要更新。所以nested适合查询频繁但更新频率低的场景

parent/child(父子类型)

join数据类型允许在一个索引中的文档创建父子关系,通过维护父子文档的关系独立出来两个对象。父文档和自文档是相互独立的,通过类似引用的关系进行绑定,所以当父文档更新时,不需要更新自文档,而自文档可以被任意的添加、修改、删除而不会影响到父文档和其他自文档

需要注意的是,为了维护父子文档的关系需要占用额外的内存资源,并且读取性能相对较差。但是由于父子文档是互相独立的,所以适合自文档更新频率高的场景

在Mapping中定义join数据类型
PUT join_books_index
{"mappings": {"properties": { "book_id": { "type": "keyword" },"name": { "type": "text" },"book_comments_relation": { # 定义字段名字"type": "join", # 此字段为 join 类型"relations": { # 声明 Parent / Child 的关系"book": "comment" # book 是 Parent 的名称,comment 是 Child 的名称}}}},"settings": {"number_of_shards": 3, # 定义 3 个主分片"number_of_replicas": 1}
}

如上示例,book_comments_relation是字段的名字,使用join关键字定义此字段的类型为join类型,relations处声明了Parent/Child的关系,其中book是Parent的名称, comment是Child的名称

索引父文档(创建)

在定义了Mapping之后,我们写入父文档的数据

image.png

索引子文档(创建)

image.png
如上所示,book_comments_relation中声明了文档的类型为comment(即mapping中的自文档),并且使用parent字段指向父文档的id

为了确保查询时候的性能,父文档和子文档必须在同一个分片,所以需要强制使用routing参数,并且其值为父文档的Id(如果写入父文档的时候也用routing参数,那么需要保证他们的值是一样的)

数据检索

image.png
返回结果:
image.png

如图所示,我们在获取父文档的数据时候是不返回子文档的信息的,因为父子文档是相互独立的

获取子文档:
image.png
如上图所示,在获取子文档时,如果不加routing参数时,是无法找到对应的子文档的。routing参数的值为父文档的Id

parent id查询

image.png
如上所示,parent_id字段里面,我们查询了父文档Id为11并且comment类型的文档

返回结果:
image.png

has child查询

如果我们想查询用户“fork”评论了那些书本,可以使用 Has Child 查询。Has Child 查询将在子文档中进行条件匹配,然后返回匹配文档对应的父文档的信息
image.png
返回结果:
image.png

has parent查询

那如果我们想查询java相关书籍的评论时,可以使用Has Parent 查询。 Has Parent 查询会在父文档中进行匹配,然后返回匹配文档对应的子文档的信息。
image.png
返回结果:
image.png

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

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

相关文章

PC电脑可以当服务器使用吗?

PC电脑是一种性能、大小适用于个人使用的多用途计算机,是由硬件系统和软件系统共同组成,能够独立运行并且完成特定功能的设备,那有的人就会问PC电脑可以当做服务器来进行使用吗?答案是可以的。 PC电脑可以当做服务器来使用&#x…

Centos 9 安装 k8s

为了尽可能契合生产环境的部署情况,这里用kubeadm安装集群,同时方便跟随笔记一步步实践的过程,也更加了解k8s的一些特性和基础知识。 先决条件 这里将通过虚拟机安装3台centos stream 9服务器,并组成kubeneters集群(…

Vue基础篇

Vue Vue是一套用于构建用户界面的渐进式JavaScript框架 什么是渐进式? Vue可以自底向上逐层地应用; 当构建简单应用时, 只需一个轻量小巧的核心库; 当构建复杂应用时, 可以引入各式各样的Vue插件 Vue具有以下特点: 采用组件化模式, 提高代码复用率且让代码更好维护 声明式编…

Vue+SpringBoot打造考研专业课程管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高校教师管理模块2.4 考研专业模块2.5 考研政策模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 考研高校表3.2.2 高校教师表3.2.3 考研专业表3.2.4 考研政策表 四、系统展示五、核…

Pandas isin()函数介绍

简介 isin() 函数是 Pandas 库中的一个非常实用的函数,主要用于筛选数据框(DataFrame)或序列(Series)中包含特定值的数据。这个函数可以接收一个列表、集合或其他可迭代对象作为参数,并返回一个布尔型的序…

10 个 Java Stream 顶级技巧,大量简化代码

Java Stream API对于 Java 开发人员来说就像一把瑞士军刀 — 它用途广泛、结构紧凑,并且可以轻松处理各种任务。 它为开发人员提供了一种函数式和声明式的方式来表达复杂的数据转换和操作,使代码更加简洁和富有表现力。 但能力越大,责任越大,有效地使用Stream API需要对最…

MySQL学习笔记(一)数据库事务隔离级别与多版本并发控制(MVCC)

一、数据库事务隔离级别 数据库事务的隔离级别有4种,由低到高分别为Read uncommitted (读未提交)、Read committed(读提交) 、Repeatable read(可重复读) 、Serializable (串行化&a…

spingboot控制器中@Autowired的变量为空问题的解决

在控制器中新创建了一个函数,前台可以调用,然后获取记录信息返回。 但是前台调用时,可以进入该函数,但是该函数调用自动注入的变量时,发现该变量为空。但是其他函数都可以正常使用自动注入的变量,该问题就…

芯片后端的APR是指什么?

APR,代表自动布局与布线(Auto Placement & Route),已经成为芯片后端设计的重要部分。在当今EDA(电子设计自动化)工具高度发展的背景下,手动摆放单元格并绘制连线已经变得不切实际。因此&…

如何在异步结果返回时进行跟踪

当我在使用多进程池时,可以通过apply_async()方法提交任务,并使用get()方法获取异步任务的结果。但是,在等待结果返回时,我们最希望能够跟踪任务的进度,以及处理已完成任务的结果。 然后针对这种问题我们最常见的方法…

如何在Spring Boot框架中打印响应的日志?

在 Spring Boot 框架中,可以使用拦截器来打印响应的日志。 通过自定义一个拦截器,可以在响应返回给客户端之前捕获响应信息,并将其记录到日志中。 以下是在 Spring Boot 框架中打印响应日志的步骤: 创建一个拦截器类&#xff0c…

国际数字影像产业园会议中心助力打造舒适高端的会议目的地

国际数字影像产业园会议中心,作为集先进技术与卓越设计于一体的现代化会议场所,正日益成为国内外高端会议活动的首选之地。其独特的建筑风格和内部设施,为与会者提供了舒适而高效的环境,让每一次大中小型会议都能达到预期的效果。…

如何关闭远程桌面连接

远程桌面连接是一种方便的技术,可以让用户通过网络远程访问其他计算机的桌面界面。有时候我们可能需要关闭这个连接。本文将向你介绍如何关闭远程桌面连接。 关闭远程桌面连接的步骤 要关闭远程桌面连接,按照以下步骤操作: 打开远程桌面连接…

最简单 导航栏 html css

dhl.html <!DOCTYPE html> <html><head><meta charset"utf-8"><title>导航栏</title><link type"text/css" rel"stylesheet" href"css/dhl.css"></head><div class"dhl&quo…

TheGraph 教程

官方文档&#xff1a; https://thegraph.com/docs/zh/quick-start/ 简介 The Graph 可以干什么&#xff0c;记录区块链上数据&#xff0c;以前都要有个后端服务和数据库&#xff0c;维护和开发成本大&#xff0c;使用The Graph&#xff0c;方便快捷节省成本 部署 核心&…

数据分析案例-二手车用户数据可视化分析(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【深度学习笔记】计算机视觉——风格迁移

风格迁移 摄影爱好者也许接触过滤波器。它能改变照片的颜色风格&#xff0c;从而使风景照更加锐利或者令人像更加美白。但一个滤波器通常只能改变照片的某个方面。如果要照片达到理想中的风格&#xff0c;可能需要尝试大量不同的组合。这个过程的复杂程度不亚于模型调参。 本…

leetcode 11.盛最多水的容器

题目链接&#xff1a;https://leetcode.cn/problems/container-with-most-water/ 题目描述 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以…

【unity实战】事件(Event)的基本实战使用

文章目录 最终效果前言一、素材二、角色金币交互1. 拾取金币2. 显示金币数UI 完结 最终效果 前言 之前我们介绍过委托的用法&#xff0c;具体可以跳转&#xff1a;【unity小技巧】委托&#xff08;Delegate&#xff09;的基础使用和介绍 这期来讲讲事件&#xff0c;使用你会发…

【SpringBoot3.x教程02】SpringBoot配置文件详解

前言&#xff1a;什么是配置文件 SpringBoot的配置文件是指用于定义和管理SpringBoot应用程序配置的文件。这些配置文件允许开发者调整和控制应用程序的行为&#xff0c;而无需改变代码。主要有两种格式的配置文件&#xff1a; 1、application.properties&#xff1a;这是一种使…