Elasticsearch索引之嵌套类型:深度剖析与实战应用

码到三十五 : 个人主页

心中有诗画,指尖舞代码,目光览世界,步履越千山,人间尽值得 !

Elasticsearch是一个基于Lucene的搜索服务器,它提供了一个分布式、多租户能力的全文搜索引擎,并带有一个基于HTTP的Web界面和基于JSON的文档。在Elasticsearch中,嵌套类型索引是一个非常重要的功能,它允许我们处理具有一对多关系的复杂数据结构。本文将深入探讨Elasticsearch中的嵌套类型索引,包括其定义、应用、查询、注意事项以及可能的替代方案。

目录

      • 前言
      • 一、嵌套类型作用
      • 二、nested 类型与object 类型的不同点
      • 三、嵌套类型的定义
      • 四、索引嵌套文档
      • 五、查询嵌套文档
      • 六、排序和聚合
      • 七、注意事项和性能考虑
      • 八、替代方案
      • 结语

前言

在Elasticsearch的实际应用中,嵌套文档是一个常见的需求,尤其是当我们需要对对象数组进行独立索引和查询时。在Elasticsearch中,这类嵌套结构被称为父子文档,它们能够“彼此独立地进行查询”。实现这一功能主要有两种方式:

  1. 父子文档关系

    • 在Elasticsearch 5.x版本中,这种关系是通过parent-child父子type来实现的,允许一个索引对应多个type。
    • 但从6.x版本开始,由于Elasticsearch不再支持单个索引对应多个type,因此父子索引的实现方式转变为使用Join数据类型。
  2. Nested嵌套类型

    • 这是一种更为紧凑和高效的方式来处理嵌套文档,允许在单个文档中直接嵌套其他文档,并保持它们之间的关联性,便于进行复杂的查询操作。

简而言之,Elasticsearch提供了灵活的方式来处理嵌套文档和父子文档关系,以满足不同场景下的查询需求。

一、嵌套类型作用

(1)Nested类型:Nested是Elasticsearch中一种特殊的数据类型,专为处理对象数组设计。它允许对数组中的每个对象进行独立的索引和查询,保持对象内部字段间的关联性。

(2)对象数组的默认存储方式

Elasticsearch内部并不直接支持对象的层次结构,而是将对象层次结构扁平化为一个字段名和字段值的简单列表。这种处理方式可能导致数据关联性的丢失。例如,考虑以下文档:

PUT user/user_info/1
{"group": "man","userName": [ {"first": "张","last": "三"},{"first": "李","last": "四"}]
}

如果我们尝试查询first为“张”且last为“四”的数据,按照常理,这样的数据应该不存在。然而,使用以下查询:

GET /user/user_info/_search
{"query": {"bool": {"must": [{"match": {"userName.first": "张"}},{"match": {"userName.last": "四"}}]}}
}

意外地,我们可能会得到结果。这是因为Lucene(Elasticsearch的底层库)没有内部对象的概念,它将内部对象扁平化处理了。在内部,文档实际上被存储为:

{"group": "man","userName.first": ["张", "李"],"userName.last": ["三", "四"]
}

可以看到,userName.firstuserName.last被扁平化为多值字段,它们之间的关联性已经丢失,因此查询结果可能不符合我们的预期。

(3)使用Nested类型解决问题

为了解决上述问题并保持对象内部字段的关联性,我们可以使用Nested类型。通过Nested类型,Elasticsearch能够正确地处理对象数组,使得我们可以对数组中的每个对象进行独立的查询,从而得到准确的结果。

二、nested 类型与object 类型的不同点

嵌套对象(nested object)相较于普通的对象(object)类型,在Elasticsearch中具有独特的特点和功能。以下是它们之间的主要差异:

嵌套对象(nested object)

  • 概述:嵌套类型是对象数据类型的一个特定版本,专为对象数组设计,使得数组中的每个对象都可以被独立地索引和查询。

  • 特征

    • 字段相关性的保留:每个嵌套对象被独立索引后,能够确保对象中字段间的相关性不被破坏。这意味着在进行查询时,可以精确地找到满足条件的特定嵌套对象。
    • 查询效率:由于嵌套文档直接内嵌在父文档中,查询嵌套文档与根文档的组合成本相对较低,从而保证了查询的高效性,其速度与单独存储文档几乎无异。
    • 数据的隐藏与访问:嵌套文档在内部是隐藏存储的,无法直接访问。若需对嵌套对象进行修改(增加、删除或更改),则必须对整个父文档进行重新索引。值得注意的是,查询时返回的是包含匹配嵌套对象的整个父文档,而非单独的嵌套文档。

相比之下,**普通的对象(object)**类型在处理对象数组时,默认会将对象内部的字段扁平化,这可能导致字段间的关联性丢失。因此,在进行复杂查询时,可能无法精确地定位到对象数组中的特定对象,从而影响查询结果的准确性。

总的来说,嵌套对象通过保留字段间的相关性和提供高效的查询性能,为处理对象数组提供了一种更为精确和灵活的方式。然而,这也带来了数据访问和修改的某些限制,需要权衡利弊后做出选择。

三、嵌套类型的定义

在Elasticsearch中,嵌套类型主要用于处理包含多个内部对象的字段,这些内部对象通常与外部对象相关联。通过在映射(mapping)中定义一个字段为嵌套类型,我们可以对这些关联数据进行有效的查询。

嵌套类型定义:

PUT /my_index
{"mappings": {"properties": {"user": {"type": "nested", "properties": {"name": {"type": "text"},"age": {"type": "integer"}}}}}
}

user字段被定义为嵌套类型,包含nameage两个子字段。这样的定义允许存储和查询多个与用户相关的内部对象。

四、索引嵌套文档

一旦定义了嵌套索引,就可以开始索引包含嵌套字段的文档了。以下是一个栗子:

PUT /my_index/_doc/1
{"user": [{"name": "Alice","age": 25},{"name": "Bob","age": 30}]
}

user字段是一个数组,每个数组元素都是一个对象,包含nameage字段。这种数据结构允许我们存储多个与用户相关的记录,并保持它们之间的关联性。

五、查询嵌套文档

查询嵌套文档时,需要使用特定的nested查询语法。以下是一个查询名字为"Alice"的用户的dsl:

GET /my_index/_search
{"query": {"nested": {"path": "user","query": {"match": {"user.name": "Alice"}}}}
}

这个查询将返回所有包含名字为"Alice"的用户的文档。通过nested查询,可以精确地定位到嵌套字段中的特定数据,并进行高效的检索。

六、排序和聚合

除了基本的查询功能外,Elasticsearch还允许我们对嵌套字段进行排序和聚合操作。然而,由于嵌套字段的特殊性,这些操作可能比常规字段更复杂。需要使用特定的nested排序和聚合语法来实现这些功能。

例如,如果我们想按照用户的年龄进行排序,可以使用以下查询:

GET /my_index/_search
{"sort": [{"user.age": {"order": "asc","nested": {"path": "user"}}}],"query": {"match_all": {}}
}

这个查询将按照用户的年龄进行升序排序,并返回所有文档。通过使用nested排序语法,我们可以确保正确地处理嵌套字段中的数据。

类似地,也可以对嵌套字段进行聚合操作,以获取有关数据的统计信息。例如,我们可以计算用户的平均年龄:

GET /my_index/_search
{"size": 0,"aggs": {"nested_users": {"nested": {"path": "user"},"aggs": {"average_age": {"avg": {"field": "user.age"}}}}}
}

这个聚合查询将计算所有用户的平均年龄,并返回结果。通过使用nested聚合语法,我们可以对嵌套字段中的数据执行复杂的统计分析。

七、注意事项和性能考虑

尽管嵌套索引在Elasticsearch中非常有用,但也有一些需要注意的事项和性能考虑因素:

  1. 性能影响:嵌套字段会增加索引的复杂性,并可能影响性能。由于嵌套字段需要额外的存储空间来维护内部对象之间的关系,因此索引和查询这些字段可能会比常规字段更耗时。
  2. 更新开销:当你更新嵌套文档中的某个内部对象时,整个嵌套数组都会被重新索引。这可能会导致性能下降,特别是在处理大量数据时。因此,在设计数据模型时需要谨慎考虑更新的频率和影响。
  3. 查询复杂性:对嵌套字段进行查询可能比常规字段更复杂。你需要使用特定的nested查询语法,并确保正确地引用嵌套路径和字段名。此外,过于复杂的查询可能会导致性能下降。

八、替代方案

如果你发现嵌套字段导致性能问题或查询复杂性增加,可以考虑以下替代方案:
在这里插入图片描述

  1. 数据模型扁平化:尝试将数据模型扁平化,将嵌套字段拆分为单独的字段或文档。这样可以简化查询和索引过程,但可能会增加数据冗余和存储开销。

  2. 父子文档关系:Elasticsearch支持父子文档关系,允许你定义文档之间的层次结构。这种关系可以用于处理具有一对多关系的数据,并提供更灵活的查询和聚合功能。然而,父子文档关系也可能带来一些性能上的考虑因素。

在这里插入图片描述

  1. 应用逻辑管理:另一种方法是将关联数据存储在单独的索引中,并使用应用程序逻辑来管理和查询这些数据之间的关系。这种方法可以提供更大的灵活性,但需要在应用程序中实现额外的逻辑来处理关联数据。

结语

Elasticsearch中的嵌套索引是一个强大的功能,允许你处理具有一对多关系的复杂数据结构。通过正确使用嵌套索引、查询、排序和聚合功能,你可以高效地检索和分析关联数据。然而,在使用嵌套索引时需要注意性能影响和查询复杂性,并根据具体情况考虑替代方案来优化数据模型和查询性能。


术因分享而日新,感谢您关注公众号 码到三十五 ,共享更多技术资料。


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

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

相关文章

如何在横向渗透攻击中寻到一线生机

横向渗透,作为计算机网络中的一种攻击技术,展现出了攻击者如何巧妙地利用同一级别系统间的漏洞和弱点,扩大其网络访问权限。与纵向渗透不同,横向渗透不关注权限的垂直提升,而是更侧重于在同一层级内扩展影响力。 横向…

(学习日记)2024.04.10:UCOSIII第三十八节:事件实验

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…

【报错】Python3.9及以上相对路径导入文件夹方式

Python3.9及以上相对路径导入文件夹 python跨文件夹调用别的文件夹下的py文件或参数方式 5.7. 包相对导入 相对导入使用前缀点号。 一个前缀点号表示相对导入从当前包开始。 两个或更多前缀点号表示对当前包的上级包的相对导入,第一个点号之后的每个点号代表一级…

二维相位解包理论算法和软件【全文翻译- 掩码(3.4)】

本节我们将研究从质量图中提取掩码的问题。掩码是一个质量图,其像素只有两个值:0 或 1。零值像素标志着质量最低的相位值,这些相位值将被屏蔽、零权重或忽略。第 5 章中的某些 L/ 正则算法需要使用掩码来定义零权重。掩码还可用于某些路径跟踪算法,如第 4.5 节中将要介绍的…

管廊ar实景可视化巡检提升安全性

在科技日新月异的今天,智慧工地ar远程巡检交互系统应运而生,它是ar开发公司深圳华锐视点综合运用了AR增强现实、5G通信、人工智能、物联网以及GPS北斗定位等前沿技术,为企业打造了一套全新的数字化巡检解决方案。不仅解放了巡检人员的双手&am…

iOS 开发中上传 IPA 文件的方法(无需 Mac 电脑

引言 在 iOS 开发中,将 IPA 文件上传到苹果开发者中心是一个重要的步骤。通常情况下,我们需要使用 Mac 电脑上的 Xcode 或 Application Loader 工具来完成这个任务。然而,如果你没有 Mac 电脑,也没有关系,本文将介绍一…

普通人想要找轻资产创业项目?抖音小店了解一下!

大家好,我是电商小布。 普通人想要创业,考虑的事情无非两点:一个是项目的发展,另一个就是项目的投入和回报。 刚开始的话,大家都是愿意来找一些小而美,轻资产的创业项目来玩的。 而现在相对来说投入不算…

DJ的打碟是什么意思 FL Studio怎么制作打碟的效果

在如今的音乐文化中,DJ打碟已经成为一种重要的表演形式和音乐创作方式。但是,对于许多人来说,仍然会对DJ的打碟到底意味着什么存在疑惑,接下来给大家介绍DJ的打碟是什么意思,FL Studio怎么制作打碟的效果的具体内容。 …

线性代数难学怎么办?到星河社区让飞桨来帮忙!

用飞桨帮我们好好学线性代数 参考自《动手学深度学习》第二章 《漫画线性代数》等。星河社区代码一键执行:线性代数难学怎么办?到星河社区让飞桨来帮忙! 线性代数,这个在数学领域举足轻重的学科,是众多学科的基础&am…

『VUE』14. Style绑定(详细图文注释)

目录 行内css动态样式对象引入数组引入代码演示总结 欢迎关注 『VUE』 专栏,持续更新中 欢迎关注 『VUE』 专栏,持续更新中 大体上和前面的class绑定是一致的,只是class换成了style. 请注意,实际开发中,我们一般建议用class,因为style的权重太高了,用sty…

【科普小文】3分钟搞懂 Apache SeaTunnel CDC 数据同步

CDC简介 CDC(Change Data Capture)是一种用于跟踪数据库库变更事件(插入、更新、删除)中的行级更改,并将事件以发生的顺序通知到其他系统处理。在容灾场景下,CDC主要实现的是主备间的数据同步,即从主数据库到备数据库…

虚拟主机WordPress网站安装教程

一般的企业官网,简站WordPress小编都推荐使用虚拟主机,用虚拟主机搭建一般的WordPress企业官网足够用了。最主要的好处是使用虚拟主机可以省去了主机维护的成本。 下面是以简站WordPress主题在虚拟主机搭建企业官网为例子,写的一个教程&…