掌握ElasticSearch(八):聚集、文档间的关系

文章目录

  • 一、聚集
    • 聚集类型
    • 示例
  • 二、文档间的关系
    • 1. 对象类型(Object Type)
    • 2. 嵌套文档(Nested Documents)
      • 定义嵌套字段
      • 索引嵌套文档
      • 查询嵌套文档
    • 3. 父子关系(Parent-Child Relationship)
      • 定义父子关系
      • 索引父文档和子文档
        • 索引父文档
        • 索引子文档
      • 查询父子关系
        • 查询父文档及其子文档
        • 查询子文档及其父文档
      • 更新父子关系
        • 更新父文档
        • 更新子文档
      • 删除父子关系
        • 删除父文档
        • 删除子文档
    • 4. 反规范化(Denormalization)
      • 示例
    • 5.性能对比

一、聚集

Elasticsearch 是一个基于 Lucene 的分布式搜索和分析引擎。它允许用户以近乎实时的方式存储、搜索和分析大量的数据。在 Elasticsearch 中,聚集(Aggregations)是一种强大的工具,用于执行复杂的汇总统计,如计数、平均值、最大值、最小值等。通过聚集,可以对数据进行深入分析,帮助我们更好地理解数据集。

聚集类型

Elasticsearch 支持多种类型的聚集,主要包括以下几类:

  1. 度量聚集(Metric Aggregations)

    • 这是最基本的聚集类型,用于计算数值字段的度量值。例如,avg(平均值)、sum(总和)、min(最小值)、max(最大值)、value_count(计数)、stats(统计数据)、extended_stats(扩展统计数据)等。
  2. 桶聚集(Bucket Aggregations)

    • 桶聚集将文档分成多个组或“桶”,每个桶代表一组满足特定条件的文档。常见的桶聚集包括:
      • terms:根据字段值分组。
      • histogram:根据数值字段创建直方图。
      • date_histogram:根据日期字段创建直方图。
      • range:根据数值或日期范围分组。
      • geo_distance:根据地理位置距离分组。
      • significant_terms:找出显著不同的术语。
  3. 管道聚集(Pipeline Aggregations)

    • 管道聚集用于处理其他聚集的结果。它们可以用于计算两个聚集结果之间的差异、百分比变化等。常用的管道聚集有 derivative(导数)、moving_avg(移动平均)、bucket_script(脚本化桶)、bucket_selector(桶选择器)等。
  4. 矩阵聚集(Matrix Aggregations)

    • 矩阵聚集用于多变量数据分析,能够计算数值字段之间的相关性和协方差等统计指标。

示例

假设我们有一个包含员工信息的数据集,我们可以使用聚集来找出不同部门的平均工资:

GET /employees/_search
{"size": 0,"aggs": {"by_department": {"terms": {"field": "department"},"aggs": {"average_salary": {"avg": {"field": "salary"}}}}}
}

在这个例子中,by_department 是一个 terms 桶聚集,它按照 department 字段的值将文档分组。然后,在每个部门的文档组中,average_salary 度量聚集计算了 salary 字段的平均值。

虽然聚集功能强大,但它们也可能消耗大量资源,特别是当处理大规模数据集时。因此,在设计查询时应该考虑到性能优化,比如减少返回的桶数量、使用合适的字段类型等。

二、文档间的关系

在 Elasticsearch 中,文档间的关系可以通过几种方式来实现,包括对象类型、嵌套文档、父子关系和反规范化。每种方法都有其适用场景和优缺点。

1. 对象类型(Object Type)

对象类型是最简单的文档内嵌方式,它允许在一个文档中嵌入另一个对象。这种方式适用于对象之间关系紧密且不需要独立索引的情况。

  • 示例:
{"name": "John Doe","address": {"street": "123 Main St","city": "Anytown","state": "Anystate"}
}
  • 优点:

  • 简单易用,适合简单的嵌入关系。

  • 查询效率高,因为所有数据都在同一个文档中。

  • 缺点:

  • 如果嵌入的对象很大或者很复杂,会导致主文档变得臃肿。

  • 嵌入的对象不能独立更新,需要重新索引整个主文档。

2. 嵌套文档(Nested Documents)

嵌套文档(Nested Documents)是 Elasticsearch 中一种高级的数据建模方式,用于处理复杂的数据结构。嵌套文档可以在主文档中嵌入多个子文档,并且每个子文档都可以独立索引和查询。这种方式特别适用于需要对嵌入对象进行精确匹配和复杂查询的场景。

  • 嵌套文档的基本概念
  1. 嵌套字段:嵌套字段是一个特殊的字段类型,它允许我们将多个子文档嵌入到主文档中。每个子文档都可以有自己的字段和值。

  2. 独立索引:嵌套文档中的每个子文档都是独立索引的,这意味着我们可以对每个子文档进行独立的查询和过滤。

  3. 精确匹配:由于嵌套文档是独立索引的,可以对嵌套文档中的字段进行精确匹配,而不会受到其他嵌套文档的影响。

定义嵌套字段

在 Elasticsearch 中,我们需要在映射(mapping)中定义嵌套字段:

PUT /my-index
{"mappings": {"properties": {"name": { "type": "text" },"interests": {"type": "nested","properties": {"name": { "type": "keyword" },"type": { "type": "keyword" }}}}}
}

在这个示例中,interests 是一个嵌套字段,它包含两个子字段:nametype

索引嵌套文档

当索引一个包含嵌套字段的文档时,Elasticsearch 会自动将嵌套字段中的每个子文档独立索引:

POST /my-index/_doc
{"name": "John Doe","interests": [{ "name": "Hiking", "type": "Outdoor" },{ "name": "Reading", "type": "Indoor" }]
}

查询嵌套文档

要查询嵌套文档,需要使用 nested 查询。以下是一个示例,查询所有兴趣为 “Hiking” 的文档:

GET /my-index/_search
{"query": {"nested": {"path": "interests","query": {"bool": {"must": [{ "match": { "interests.name": "Hiking" }}]}}}}
}
  1. 性能:嵌套文档会增加索引和查询的复杂度,因为每个嵌套文档都需要独立索引。如果有大量的嵌套文档,可能会对性能产生影响。

  2. 内存占用:嵌套文档会占用更多的内存,因为每个嵌套文档都需要独立存储和索引。

  3. 更新复杂度:更新嵌套文档需要重新索引整个主文档,这可能会导致额外的开销。

3. 父子关系(Parent-Child Relationship)

在 Elasticsearch 中,父子关系(Parent-Child Relationship)是一种用于处理多级文档关系的方法。这种关系允许将一个文档(子文档)关联到另一个文档(父文档),并且每个子文档可以独立索引和查询。这种方法适用于需要保持文档间关系但又希望每个文档都能独立操作的场景。

  • 父子关系的基本概念
  1. 父文档(Parent Document):父文档是主要的文档,可以包含多个子文档。
  2. 子文档(Child Document):子文档是依赖于父文档的文档,每个子文档都关联到一个父文档。
  3. 关系类型(Join Field):为了建立父子关系,需要在文档中定义一个特殊的关系类型字段,称为 join field

定义父子关系

在 Elasticsearch 中,需要在索引映射(mapping)中定义关系类型字段:

PUT /my-index
{"mappings": {"properties": {"my_join_field": {"type": "join","relations": {"question": "answer"}},"title": { "type": "text" },"content": { "type": "text" }}}
}

在这个示例中,my_join_field 是一个关系类型字段,定义了两种关系:questionanswerquestion 是父文档类型,answer 是子文档类型。

索引父文档和子文档

索引父文档
POST /my-index/_doc
{"title": "What is the capital of France?","my_join_field": {"name": "question"}
}
索引子文档
POST /my-index/_doc?routing=1
{"content": "The capital of France is Paris.","my_join_field": {"name": "answer","parent": "1"}
}

在这个示例中,routing 参数指定了父文档的 ID,my_join_field 中的 parent 字段也指定了父文档的 ID。

查询父子关系

查询父文档及其子文档

要查询父文档及其子文档,可以使用 has_childhas_parent 查询。以下是一个示例,查询所有有答案的问题:

GET /my-index/_search
{"query": {"has_child": {"type": "answer","query": {"match_all": {}}}}
}
查询子文档及其父文档

以下是一个示例,查询所有答案及其对应的问题:

GET /my-index/_search
{"query": {"has_parent": {"parent_type": "question","query": {"match_all": {}}}}
}

更新父子关系

更新父子关系文档需要重新索引整个文档。可以使用 update API 来更新文档:

更新父文档
POST /my-index/_update/1
{"doc": {"title": "What is the capital of France? (Updated)"}
}
更新子文档
POST /my-index/_update/2?routing=1
{"doc": {"content": "The capital of France is Paris. (Updated)"}
}

删除父子关系

删除父子关系文档时,可以直接删除相应的文档。删除父文档会自动删除其所有子文档,但删除子文档不会影响父文档。

删除父文档
DELETE /my-index/_doc/1
删除子文档
DELETE /my-index/_doc/2?routing=1
  • 注意事项:
  1. 性能:父子关系查询可能比普通查询慢,因为需要跨文档进行关联。
  2. 内存占用:父子关系会占用更多的内存,因为每个文档都需要独立存储和索引。
  3. 路由:在索引和查询子文档时,必须指定父文档的 ID 作为路由参数,以确保父子文档在同一分片上。

4. 反规范化(Denormalization)

反规范化(Denormalization)是数据建模的一种技术,通过在文档中重复存储相关数据来提高查询性能。在 Elasticsearch 中,反规范化是一种常见的做法,尤其适用于读多写少的场景。通过减少查询时的文档关联和连接操作,反规范化可以显著提升查询速度。

  • 反规范化的概念:

在传统的关系型数据库中,数据通常是规范化存储的,即每个实体(表)只存储一次,通过外键来建立实体之间的关系。这种方式有助于保持数据的一致性和减少数据冗余,但在查询时需要进行多次表连接操作,这可能会导致性能瓶颈。

相比之下,反规范化通过在文档中重复存储相关数据来避免这些连接操作。虽然这样做会增加数据冗余,但可以显著提高查询性能,特别是在处理大规模数据集时。

  • 反规范化的应用场景:
  1. 读多写少:如果应用程序中读取操作远多于写入操作,反规范化可以显著提高读取性能。
  2. 实时分析:在需要实时分析和快速响应的场景中,反规范化可以减少查询延迟。
  3. 复杂查询:对于需要进行复杂聚合和过滤的查询,反规范化可以简化查询逻辑,提高查询效率。

示例

假设我们有一个电子商务系统,其中包含商品(Product)和订单(Order)两个实体。在关系型数据库中,这两个实体可能分别存储在不同的表中,并通过外键关联。在 Elasticsearch 中,可以通过反规范化将订单信息嵌入到商品文档中,或者将商品信息嵌入到订单文档中。

  • 规范化模型:
// 商品文档
{"product_id": 1,"name": "iPhone 12","category": "Electronics"
}// 订单文档
{"order_id": 101,"customer_name": "John Doe","product_id": 1,"quantity": 2,"total_price": 1998
}
  • 反规范化模型:

(1)将订单信息嵌入到商品文档中

{"product_id": 1,"name": "iPhone 12","category": "Electronics","orders": [{"order_id": 101,"customer_name": "John Doe","quantity": 2,"total_price": 1998}]
}

(2)将商品信息嵌入到订单文档中

{"order_id": 101,"customer_name": "John Doe","product": {"product_id": 1,"name": "iPhone 12","category": "Electronics"},"quantity": 2,"total_price": 1998
}
  • 反规范化的优点:
  1. 查询性能:通过减少文档间的关联和连接操作,查询性能可以显著提高。
  2. 简化查询:反规范化可以简化查询逻辑,使得查询更加直观和高效。
  3. 实时分析:对于需要实时分析和快速响应的场景,反规范化可以减少查询延迟。
  • 反规范化的缺点:
  1. 数据冗余:反规范化会导致数据冗余,占用更多的存储空间。
  2. 更新复杂度:更新数据时需要同步更新多个文档,增加了数据维护的复杂度。
  3. 数据一致性:数据冗余可能导致数据不一致的风险,需要额外的机制来保证数据的一致性。
  • 实践建议:
  1. 选择合适的反规范化策略:根据具体的应用场景和需求,选择合适的反规范化策略。例如,如果订单信息频繁更新,可以考虑将商品信息嵌入到订单文档中,反之亦然。
  2. 使用版本控制:在更新数据时,使用版本控制机制来确保数据的一致性。
  3. 定期清理冗余数据:定期检查和清理冗余数据,以减少存储空间的占用。
  4. 监控和优化:持续监控系统的性能,根据实际情况进行优化调整。

5.性能对比

  • 对象类型嵌套文档 适用于简单的嵌入关系,查询性能高,但不适合复杂的数据结构。
  • 父子关系 适用于需要独立索引但又保持关联关系的场景,但查询性能较低。
  • 反规范化 适用于读多写少的场景,查询性能高,但数据冗余。

与关系型数据库相比,Elasticsearch 在处理大规模数据集时具有更高的查询性能,但牺牲了一定的数据一致性和更新复杂度。选择哪种方式取决于具体的应用场景和需求。

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

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

相关文章

AIGC时代LaTeX排版的应用、技巧与未来展望

文章目录 一、LaTeX简介与基础设置二、常用特殊符号与公式排版三、图片与表格的插入与排版四、自动编号与交叉引用五、自定义命令与样式六、LaTeX在AIGC时代的应用与挑战七、LaTeX的未来展望《LaTeX 入门实战》内容简介作者简介目录前言/序言读者对象本书内容充分利用本书 在AI…

Ansible 部署应用

Ansible Ansible 是基于 Python 开发,集合了众多优秀运维工具的优点,实现了批量运行命令、部署程序、配置系统等功能的自动化运维管理工具。默认通过 SSH 协议进行远程命令执行或下发配置,无需部署任何客户端代理软件,从而使得自动…

基于SpringBoot+Gpt个人健康管家管理系统【提供源码+答辩PPT+参考文档+项目部署】

作者简介:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容:🌟Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…

React中常用的hook函数(三)——useReducer和useContext

React中常用的hook函数(一)——useState和useEffect_usestate useeffect-CSDN博客https://blog.csdn.net/Mrs_Lupin/article/details/142905749?sharetypeblogdetail&sharerId142905749&sharereferPC&sharesourceMrs_Lupin&spm1011.2480.3001.8118React中常用…

Android问题 -- DJ多多的下载文件在哪里? DJ多多dat格式转换为mp3

目的 想要将安卓 DJ多多 应用所下载的歌曲文件转换为 mp3 格式, 以便于传输到手表上进行播放 (健身跑步用) 但是找不到在安卓手机中DJ多多的下载的文件路径 文件路径 使用 ES文件浏览器 查看, 自带文件管理器一般查不到 文件路径: 内部存储/Android/data/com.shoujiduoduo.…

使用 Elastic、OpenLLMetry 和 OpenTelemetry 跟踪 LangChain 应用程序

作者:来自 Elastic Bahubali Shetti Langchain 应用程序的使用正在增长。构建基于 RAG 的应用程序、简单的 AI 助手等的能力正在成为常态。观察这些应用程序更加困难。考虑到现有的各种选项,本博客展示了如何将 OpenTelemetry 检测与 OpenLLMetry 结合使…

如何使用Web-Check和cpolar实现安全的远程网站监测与管理

文章目录 前言1.关于Web-Check2.功能特点3.安装Docker4.创建并启动Web-Check容器5.本地访问测试6.公网远程访问本地Web-Check7.内网穿透工具安装8.创建远程连接公网地址9.使用固定公网地址远程访问 前言 本期给大家分享一个网站检测工具Web-Check,能帮你全面了解网…

LabVIEW适合开发的软件

LabVIEW作为一种图形化编程环境,主要用于测试、测量和控制系统的开发。以下是LabVIEW在不同应用场景中的适用性和优势。 一、测试与测量系统 LabVIEW在测试与测量系统中的应用广泛,是工程测试领域的主流工具之一。利用其强大的数据采集与处理功能&…

面试题:JVM(四)

new对象流程?(龙湖地产) 对象创建方法,对象的内存分配。(360安全) 1. 对象实例化 创建对象的方式有几种? 创建对象的步骤 指针碰撞:以指针为分界线,一边是已连续使用的…

ERP研究 | 颜值美和道德美,哪个更重要?

摘要 道德美和颜值美都会影响我们的评价。在这里,本研究采用事件相关电位(ERPs)技术探讨了道德美和颜值美如何交互影响社会判断和情感反应。参与者(均为女性)将积极、中性或消极的言语信息与高吸引力或低吸引力面孔进行关联,并对这些面孔进行评分&#…

CSS中常见的两列布局、三列布局、百分比和多行多列布局!

目录 一、两列布局 1、前言: 2. 两列布局的常见用法 两列布局的元素示例: 代码运行后如下: 二、三列布局 1.前言 2. 三列布局的常见用法 三列布局的元素示例: 代码运行后如下: 三、多行多列 1.前言 2&…

Vue3版本的uniapp项目运行至鸿蒙系统

新建Vue3版本的uniapp项目 注意,先将HbuilderX升级至最新版本,这样才支持鸿蒙系统的调试与运行; 按照如下图片点击,快速升级皆可。 通过HbuilderX创建 官方文档指导链接 点击HbuilderX中左上角文件->新建->项目 创建vue3…

Nature文章《deep learning》文章翻译

这篇文章是对Nature上《deep learning》文章的翻译。原作者 Yann LeCun, Yoshua Bengio& Geoffrey Hinton。 这篇文章的中心思想是深入探讨深度学习在机器学习中的革命性贡献,重点介绍其在特征学习、监督学习、无监督学习等方面的突破,并阐述其在图…

AnaTraf | 全流量回溯分析:网络故障排除的 “时光回溯机”

AnaTraf 网络性能监控系统NPM | 全流量回溯分析 | 网络故障排除工具AnaTraf网络流量分析仪是一款基于全流量,能够实时监控网络流量和历史流量回溯分析的网络性能监控与诊断系统(NPMD)。通过对网络各个关键节点的监测,收集网络性能…

Zabbix低权限SQL注入至RCE+权限绕过

Zabbix低权限SQL注入至RCE权限绕过,可惜没找到关于传webshell的好方法,如有大神告知,感激万分! 本文中所有代码以及后续更新都会放在我的github仓库中: https://github.com/W01fh4cker/CVE-2024-22120-RCE 一、漏洞环…

[vulnhub]DC: 1

https://www.vulnhub.com/entry/dc-1,292/ 主机发现端口扫描 使用nmap扫描网段类存活主机 因为靶机是我最后添加的,所以靶机IP是156 nmap -sP 192.168.75.0/24 // Starting Nmap 7.93 ( https://nmap.org ) at 2024-09-28 12:48 CST Nmap scan rep…

jmeter脚本-请求体设置变量and请求体太长的处理

目录 1、查询接口 1.1 准备组织列表的TXT文件,如下: 1.2 添加 CSV数据文件设置 ,如下: 1.3 接口请求体设置变量,如下: 2、创建接口 2.1 见1.1 2.2 见1.2 2.3 准备创建接口的请求体TXT文件&#xff…

SQL,力扣题目1549,每件商品的最新订单【窗口函数】

一、力扣链接 LeetCode_1549 二、题目描述 表: Customers ------------------------ | Column Name | Type | ------------------------ | customer_id | int | | name | varchar | ------------------------ customer_id 是该表主键. 该表包含消费者的…

卸载 Adobe Genuine Software Client

一、问题描述 使用破jie版Adobe Acrobat Pro DC软件后,会经常弹出以下窗口: 且上述探窗无法直接关掉。即使通过任务管理器将其临时关掉,可等过一段时间后,仍然会再次弹出,严重干扰工作进度。 二、问题解决 &#xff…