首页
学习
活动
专区
圈层
工具
发布

Elasticsearch获取嵌套字段

Elasticsearch 嵌套字段获取指南

基础概念

Elasticsearch 中的嵌套字段(nested field)是一种特殊的数据类型,用于处理对象数组(object arrays)中的独立对象。与普通的对象数组不同,嵌套字段中的每个对象都是独立的文档,可以单独查询而不影响数组中的其他对象。

为什么需要嵌套字段

在默认情况下,Elasticsearch 会将对象数组扁平化处理。例如:

代码语言:txt
复制
{
  "user": [
    {"first": "John", "last": "Smith"},
    {"first": "Alice", "last": "White"}
  ]
}

会被存储为:

代码语言:txt
复制
user.first: ["John", "Alice"]
user.last: ["Smith", "White"]

这会导致查询时无法关联同一对象中的字段。

嵌套字段的优势

  1. 保持对象内部字段的关联性
  2. 支持对嵌套对象进行独立查询
  3. 允许对嵌套对象进行聚合操作
  4. 提供更精确的搜索能力

定义嵌套字段

在映射中定义嵌套字段:

代码语言:txt
复制
PUT my_index
{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested" 
      }
    }
  }
}

查询嵌套字段

1. 基本嵌套查询

代码语言:txt
复制
GET my_index/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last": "White" }}
          ]
        }
      }
    }
  }
}

2. 嵌套聚合

代码语言:txt
复制
GET my_index/_search
{
  "aggs": {
    "users": {
      "nested": {
        "path": "user"
      },
      "aggs": {
        "names": {
          "terms": { "field": "user.first" }
        }
      }
    }
  }
}

3. 获取嵌套字段值

使用 inner_hits 获取匹配的嵌套对象:

代码语言:txt
复制
GET my_index/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": { "match": { "user.first": "Alice" } },
      "inner_hits": {}
    }
  }
}

常见问题及解决方案

问题1:无法正确查询嵌套对象中的字段

原因:可能没有正确定义字段为嵌套类型,或者使用了普通的对象查询方式。

解决方案

  1. 确保映射中字段类型为 nested
  2. 使用 nested 查询而非普通查询

问题2:查询性能慢

原因:嵌套查询需要额外的资源来处理嵌套文档。

解决方案

  1. 限制嵌套查询的范围
  2. 使用 ignore_unmapped 参数避免不必要的处理
  3. 考虑数据模型是否需要重构

问题3:无法获取嵌套对象的位置信息

解决方案: 使用 inner_hits 并配置 docvalue_fieldsstored_fields 来获取嵌套对象的原始位置信息。

应用场景

  1. 电子商务:产品属性(如不同尺寸的价格)
  2. 社交网络:用户的多重身份信息
  3. 日志分析:包含多个错误条目的日志文件
  4. 内容管理:文章的多个版本或翻译

示例代码

索引嵌套文档

代码语言:txt
复制
PUT my_index/_doc/1
{
  "user": [
    {
      "first": "John",
      "last": "Smith",
      "age": 30
    },
    {
      "first": "Alice",
      "last": "White",
      "age": 25
    }
  ]
}

复杂嵌套查询

代码语言:txt
复制
GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "user",
            "query": {
              "bool": {
                "must": [
                  { "match": { "user.first": "Alice" }},
                  { "range": { "user.age": { "gte": 20 }}}
                ]
              }
            },
            "inner_hits": {
              "size": 1,
              "_source": ["user.first", "user.last"]
            }
          }
        }
      ]
    }
  }
}

通过正确使用嵌套字段,可以有效地处理复杂的数据结构关系,实现更精确的数据查询和分析。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Elasticsearch学习-嵌套文档

本文以Elasticsearch 6.8.4版本为例,介绍Elasticsearch嵌套文档的使用。...在Elasticsearch取消了多个索引内创建多个type的机制,由于场景需要,所以调研了嵌套文档和父子文档 [image] 以文章和文章留言为例,嵌套文档都在一个文档内,而父子文档则分开存储了父文档与子文档...1、嵌套文档 嵌套文档看似与文档内有一个集合字段类似,但是实则有很大区别,以上面图中嵌套文档为例,留言1,留言2,留言3虽然都在当前文章所在的文档内,但是在内部其实存储为4个独立文档,如下图所示。...[image] 同时,嵌套文档的字段类型需要设置为nested,设置成nested后的不能被直接查询,需要使用nested查询,这里不做具体介绍,详细查看1.2。...1.4 排序 可能有一些场景需要按照嵌套文档的字段记性排序,举例: 为了符合上述场景,新增两条数据: PUT http://localhost:9200/blog/blog/2/ { "title"

1.3K00
  • Elasticsearch使用:嵌套对象

    简介 官网地址:https://www.elastic.co/guide/cn/elasticsearch/guide/current/nested-objects.html 由于在 Elasticsearch...不仅如此,由于嵌套文档直接存储在文档内部,查询时嵌套文档和根文档联合成本很低,速度和单独存储几乎一样。 嵌套文档是隐藏存储的,我们不能直接获取。...至此,所有 comments 对象会被索引在独立的嵌套文档中。可以查看 nested 类型参考文档 获取更多详细信息。 嵌套对象查询 由于嵌套对象 被索引在独立隐藏的文档中,我们无法直接查询它们。...使用嵌套字段排序 尽管嵌套字段的值存储于独立的嵌套文档中,但依然有方法按照嵌套字段的值排序。...嵌套聚合 在查询的时候,我们使用 nested 查询就可以获取嵌套对象的信息。同理, nested 聚合允许我们对嵌套对象里的字段进行聚合操作。

    6.9K81

    SQL嵌套查询_sql嵌套查询返回多个字段

    说到嵌套查询,首先得理解嵌套查询是什么意思,简单来说就是,一个查询语句可以嵌套在另外一个查询语句的where子句中。外层的查询称为父查询(主查询),内层的查询称为子查询(从查询)。...嵌套查询的工作方式是由内向外的,即先进行内层查询,外层查询则利用内层查询的结果集作为条件进行查询。...当然,嵌套查询不仅仅是select语句的专属,它还可以用在update、insert、delete语句中。...SELECT age FROM sys_user WHERE user_id = ‘1001’ ),这句语句的意思是,从sys_user表查出年龄比user_id为1001的user_name (2) IN嵌套查询...(3 )exists嵌套查询 SELECT * FRO sys_user WHERE EXISTS (SELECT * FROM sys_user WHER user_id = ‘1001’), exists

    3.7K20

    ElasticSearch嵌套模型基本操作

    上篇介绍了ES嵌套模型使用场景和优缺点,本篇接着介绍关于ES嵌套的索引一些基本的操作,包括插入,追加,更新,删除,查询单独放下一篇文章介绍。...其关系是一对多对多,User里面有个List字段可以包含多个Quest对象而每一个Quest对象又包含一个List字段可以包含多个Kp实体,每个实体类本身又可以拥有多个自己的属性字段...在这里其实也能感受到用动态索引模板的好处,就是我不要关注到底有多少个字段,我的实体类里面随时可以新增一个字段或多个字段进行索引,当然前提是你把动态模板的schema给定义好,这过程中也遇到一些问题,后面会在相关的文章中介绍...(3)在第二层嵌套数据里面删除一条quests数据 (4)在第三层嵌套数据里面添加一条Kp数据 (5)在第三层嵌套数据里面删除一条Kp数据 (6)更新第三层嵌套里面的数据 A:如果是字段数比较多,大范围更新...,建议直接删除后添加 B: 如果字段数比较少,小范围更新,就使用下面的局部更新的API即可 (7)同理更新第二层嵌套里面的数据 总结: 本篇介绍了ES嵌套索引的添加,修改,删除的操作,我们不难发现都是用

    2K50

    sql嵌套查询效率_sql嵌套查询返回多个字段

    文章目录 问题 解决 问题 为了查询一个字段,使用了五层嵌套循环,但是花费了约1分钟 但是5个表的数据每个最多只有10条,怎么会这么慢呢?...内存中有student表 接着是找WHERE关键字,如果找不到则返回到SELECT找字段解析 SELECT * FROM studet WHERE stu_id=1 如果找到WHERE,则分析其中的条件...,完成后再回到SELECT分析字段。...(这也是为什么嵌套的SQL语句SELECT 后面为一般为的原因,因为它EXISTS返回的只是真或假,字段的名没有意义,用就行,当然用别的也不会错。...) 这里虽然嵌套的SQL语句分析完了,但主SQL语句只执行了一遍,也就是说p1指向Student的第一条记录,p1还要再指向Student表的下一条记录并分析,这样又进入了嵌套中的SQL语句,同上面说的一样分析

    3.5K20

    Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?

    https://elasticsearch.cn/question/13135 如下所示, 希望在查出的结果后, 对结果进行后处理,对tags列表,根据depth进行排序。...能支持的排序方式罗列如下: 包含但不限于: 基于特定字段的排序 基于Nested对象字段的排序 基于特定脚本实现的排序 等等.........字段排序分类中的:基于特定字段的排序和基于 Nested 对象字段的排序,是对整个查询结果集进行排序,这在 Elasticsearch 中通常是针对顶层文档字段或者简单嵌套字段进行的。...在 Elasticsearch 中处理大量数据时运行复杂的脚本可能会消耗较多的计算资源! 还有,冒泡排序是一种效率较低的排序算法,特别是对于大列表,其性能不是最佳的。...相比于使用 Elasticsearch 内置的排序功能,手动实现排序算法增加了脚本的复杂性。

    96310

    浅谈ElasticSearch的嵌套存储模型

    最近一个半月都在搞SparkStreaming+Hbase+Redis+ES相关的实时流项目开发,其中重度使用了ElasticSearch作为一个核心业务的数据存储,所以这段时间更新文章较少,现在开发基本完事...总共是三层模型,可以看到User(用户)包含多个Quest(题目),每个题目又包含多个Kp(知识点),其中User,Quest,Kp都是一个实体类,可以包含多个属性,按照es的字段类型应该叫做object...,但是每一层的数据量越大,性能可能就越低,所以嵌套方案,适合存储和查询多级嵌套数据,且更新和删除操作少的业务情况,尽量没有修改和删除。...es的嵌套查询和聚合支持都比较完善,并且支持嵌套反转查询。嵌套数据的添加可以使用script脚本方式来完成,直接将Java的bean给转换完为json提交即可。...这样以来就相当于设置了三层嵌套。 到此我们应该能理解嵌套模型的定义和使用场景了,下篇会给出如何插入数据和使用script追加数据以及简单查询。

    2.1K60

    Elasticsearch 优化查询中获取字段内容的方式,性能提升5倍!

    search { "query": { "match_all": {} // 或者是其他符合你需求的查询 }, "stored_fields": ["none"], // 不获取任何存储的字段..."docvalue_fields": ["field1", "field2"] // 只获取需要的doc value字段 } 3、优化后效率 3.1 查询耗时有进一步的提升 3.2 压测时cpu...4、优化根因分析 在优化前,由于Elasticsearch默认从_source字段读取数据,这导致每次查询都需要读取整行数据并进行解压。...而使用“docvalue_fields”指定从列存中获取字段内容,没有压缩的转换,进一步减少了数据处理的开销。这种方法不仅降低了CPU的使用率,同时只提取必要的字段也减少了了网络传输的负担。...金多安,Elastic 认证专家,Elastic资深运维工程师,死磕Elasticsearch知识星球嘉宾,星球Top活跃技术专家,搜索客社区日报责任编辑

    1.1K10

    Elasticsearch聚合的嵌套桶如何排序

    关于嵌套桶 在elasticsearch的聚合查询中,经常对聚合的数据再次做聚合处理,例如统计每个汽车品牌下的每种颜色汽车的销售额,这时候DSL中就有了多层aggs对象的嵌套,这就是嵌套桶(此名称来自...Kibana:6.7.1 实例数据 查询用到的数据是个名为cars的索引,里面保存了多条汽车销售记录,字段有品牌(make)、颜色(color)、价格(price)、售卖时间(sold)等,在elasticsearch-head...内层桶是外层桶的数据过滤生成的,例如统计每个汽车品牌下红色汽车的销售额,先按照品牌聚合,再对外层桶按照颜色做过滤,这样的嵌套是可以用内层桶字段的值来排序的,DSL如下: GET /cars/transactions...,是否能进行整体排序的关键就在于整个嵌套路径中,是否有多值的桶出现,如果没有就可以用嵌套内部的字段进行排序,除了上面的filter,还有global 和reverse_nested 这两种桶类型生成的也是单值桶...,因此也可以用其内部的字段进行排序; 至此,嵌套桶的聚合结果排序已经实践完毕了,希望您在面对类似排序问题时,此文能给您一些参考。

    4.4K20

    ElasticSearch的Mapping之字段类型

    "store":false//是否单独设置此字段的是否存储而从_source字段中分离,默认是false,只能搜索,不能获取值 "search_analyzer...,任何一个字段的值,都可以被添加0个到多个,要求,他们的类型必须一致: 对象类型:存储类似json具有层级的数据 嵌套类型:支持数组类型的对象Aarray[Object],可层层嵌套 (4)地理类型...:安装sudo bin/plugin install mapper-size插件,可支持_size统计_source数据的大小 附件类型:需要https://github.com/elastic/elasticsearch-mapper-attachments...type,对象字段和嵌套字段可以包含子字段,这些属性可以被添加进去,例子如下 ?...官网文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html#_multi_fields

    1.9K50

    elasticsearch中Flattened字段的介绍

    仅为整个 JSON 对象创建一个字段映射,这可以帮助防止由于大量不同的字段映射而导致映射爆炸。...整个 JSON 对象只创建一个字段映射,这有助于防止由于过多不同的字段映射而导致的映射爆炸。另一方面,扁平化对象字段在搜索功能方面存在权衡。仅允许基本查询,不支持数值范围查询或高亮显示。...TIPS: 扁平化对象字段目前无法存储。在映射中无法指定 store 参数。检索扁平化字段字段值和具体子字段可以通过 fields 参数获取。...由于 flattened 字段将整个对象(可能包含许多子字段)映射为单个字段,响应包含来自 _source 的未修改结构。然而,单个子字段可以通过在请求中明确指定来获取。...labels.release'].value)} else{emit('Version mismatch')} """官方文档: https://www.elastic.co/guide/en/elasticsearch

    24400

    elasticsearch分页获取数据

    提到elasticsearch分页,可能首先想到的是类似mysql的那种处理方式,传入分页起始值以及每页数据量,es确实提供了类似的处理策略,代码如下: @Test public void searchFromSize...s.getSourceAsString()); } } 但是上述方式有一个严重的缺陷:from和size不能太大,两者之和不能超过index.max_result_window,超过该值就会报 org.elasticsearch.client.ResponseException...以此来返回全局排序前10的数据,如果有类似的需要可以使用scroll以及search after来实现超大分页问题, scroll分页示例代码可以参考:https://www.elastic.co/guide/en/elasticsearch...QueryBuilders.matchQuery("cityId", "511000")); searchSourceBuilder.size(2); //id动态映射为text类型,排序不能使用分词的字段...,所以这里选择了id的keyword多字段属性 searchSourceBuilder.sort(new FieldSortBuilder("id.keyword").order(SortOrder.ASC

    1.3K10
    领券