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

这篇具有很好参考价值的文章主要介绍了Elasticsearch索引之嵌套类型:深度剖析与实战应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

码到三十五 : 个人主页

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

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

前言

在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查询语法,并确保正确地引用嵌套路径和字段名。此外,过于复杂的查询可能会导致性能下降。

八、替代方案

如果你发现嵌套字段导致性能问题或查询复杂性增加,可以考虑以下替代方案:
Elasticsearch索引之嵌套类型:深度剖析与实战应用,数据核心,计算机视觉,elasticsearch,搜索引擎,大数据,数据仓库

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

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

Elasticsearch索引之嵌套类型:深度剖析与实战应用,数据核心,计算机视觉,elasticsearch,搜索引擎,大数据,数据仓库

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

结语

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


术因分享而日新,感谢您关注公众号 码到三十五 ,共享更多技术资料。文章来源地址https://www.toymoban.com/news/detail-845214.html


到了这里,关于Elasticsearch索引之嵌套类型:深度剖析与实战应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 04_手工画图剖析Elasticsearch核心概念:NRT、索引、分片、副本等

    2.elasticsearch的核心概念 (1)Near Realtime (NRT):近实时, 从写入数据到数据可以被搜索到有一个小延迟(大概1秒);基于es执行搜索和分析可以达到秒级 (2) cluster集群:包括多个节点, 每个节点属于哪个集群是通过一个配置(集群名称,默认是elasticsearch)来决定的, 对于中小型

    2024年02月09日
    浏览(39)
  • Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?

    这是来自社区的一个真实企业场景问题。 https://elasticsearch.cn/question/13135 如下所示, 希望在查出的结果后, 对结果进行后处理,对tags列表,根据depth进行排序。 Elasticsearch 能支持的排序方式罗列如下: 包含但不限于: 基于特定字段的排序 基于Nested对象字段的排序 基于特定

    2024年02月02日
    浏览(42)
  • ElasticSearch修改索引字段类型

    线上功能报错,一看日志是往es中添加数据报错,错误日志如下: 说是数据中有个字段类型转换错误,一查es脚本工具,果然生产es索引中categoryId这个字段是integer类型,而实际是long类型。 es不能直接修改索引字段类型,需要删除调新建,具体方法如下 我这次遇到问题的es索引

    2023年04月08日
    浏览(27)
  • 深度剖析动态规划算法:原理、优势与实战

    动态规划是一种优化技术,通常用于解决那些可以分解为子问题的问题。它的核心思想是将大问题分解成小问题,通过解决小问题来构建大问题的解。这种方法通常用于解决最优化问题,其中目标是找到最佳解决方案,通常是最大化或最小化某个值。 动态规划算法的核心原理

    2024年02月07日
    浏览(29)
  • Elasticsearch 索引管理:使用别名来修改字段类型

    在 Elasticsearch 中,一个常见的问题是如何修改已存在的索引的字段类型。这是一个棘手的问题,因为 Elasticsearch 本身不允许直接修改字段类型。如果删除现有索引,重新建索引的话则会导致数据丢失。有一个方法是使用别名索引,当需要调整索引时可以先新建一个索引,把数

    2024年02月03日
    浏览(32)
  • Elasticsearch:更改索引中字段的数据类型的方法

    1.问题描述:         需要将已有索引中的已有字段作为新的查询条件,需求中需要对该字段进行范围查询,当前字段为keyword类型的数字,此时发现查询所得结果与预期不符合。 2.问题拆解: 2.1发现问题: 索引字段数据类型不合理 2.2问题本质: 需要将keyword类型的转换成

    2024年02月08日
    浏览(34)
  • ElasticSearch创建后的索引如何修改数据类型

    一、前言 在 Elasticsearch 中,一旦创建索引,就不能更改现有字段的数据类型。如果您需要更改数据类型,则需要重新创建索引并使用新的数据类型。以下针对各种业务场景总结几种修改方法。 二、【方法一】删除重建 这种方式的使用场景为当前索引库数据量不大,而且可

    2024年02月13日
    浏览(39)
  • 决策树C4.5算法的技术深度剖析、实战解读

    在本篇深入探讨的文章中,我们全面分析了C4.5决策树算法,包括其核心原理、实现流程、实战案例,以及与其他流行决策树算法(如ID3、CART和Random Forests)的比较。 关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦

    2024年02月08日
    浏览(32)
  • 深度剖析Redis:从基础到高级应用

    目录 引言 1、 Redis基础 1.1 Redis数据结构 1.1.1 字符串(String) 1.1.2 列表(List) 1.1.3 集合(Set) 1.1.4 散列(Hash) 1.1.5 有序集合(Sorted Set) 1.1.6 位图(Bitmap) 1.1.7 HyperLogLog 1.1.8 地理位置(Geospatial) 1.2 Redis持久化 1.2.1 RDB快照 1.2.2 AOF日志 1.3 主从复制 1.3.1 主从复制工作原理

    2024年01月19日
    浏览(25)
  • 深度剖析数据在内存中的存储——int类型(整型)和float类型(浮点数)在内存中是如何存储和使用的?

    众所周知,C语言中有几种基本的内置数据类型: char - 字符数据类型 short - 短整型 int - 整型 long - 长整型 long long - 更长的整型 float - 单精度浮点数 double - 双精度浮点数 那为什么要设置这么多内置数据类型呢?类型的意义是什么? 本文将为大家介绍整型和浮点数在内存中的存

    2023年04月22日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包