[ElasticSearch]嵌套对象之嵌套类型

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: nested类型是一种特殊的对象object数据类型(specialised version of the object datatype ),允许对象数组彼此独立地进行索引和查询。

nested类型是一种特殊的对象object数据类型(specialised version of the object datatype ),允许对象数组彼此独立地进行索引和查询。

1. 对象数组如何扁平化

内部对象object字段的数组不能像我们所期望的那样工作。 Lucene没有内部对象的概念,所以Elasticsearch将对象层次结构扁平化为一个字段名称和值的简单列表。 例如,以下文件:

curl -XPUT 'localhost:9200/my_index/my_type/1?pretty' -H 'Content-Type: application/json' -d'
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
'

说明

user字段被动态的添加为object类型的字段。

在内部其转换成一个看起来像下面这样的文档:

{
  "group" :        "fans",
  "user.first" : [ "alice", "john" ],
  "user.last" :  [ "smith", "white" ]
}

user.firstuser.last字段被扁平化为多值字段,并且alicewhite之间的关联已经丢失。 本文档将错误地匹配user.firstaliceuser.lastsmith的查询:

curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "bool": {
      "must": [
        { "match": { "user.first": "Alice" }},
        { "match": { "user.last":  "Smith" }}
      ]
    }
  }
}
'

2. 对对象数组使用嵌套字段

如果需要索引对象数组并维护数组中每个对象的独立性,则应使用nested数据类型而不是object数据类型。 在内部,嵌套对象将数组中的每个对象作为单独的隐藏文档进行索引,这意味着每个嵌套对象都可以使用嵌套查询nested query独立于其他对象进行查询:

curl -XPUT 'localhost:9200/my_index?pretty' -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "my_type": {
      "properties": {
        "user": {
          "type": "nested" 
        }
      }
    }
  }
}
'

curl -XPUT 'localhost:9200/my_index/my_type/1?pretty' -H 'Content-Type: application/json' -d'
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
'

说明

user字段映射为nested类型,而不是默认的object类型

curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "Smith" }} 
          ]
        }
      }
    }
  }
}
'

说明

此查询得不到匹配,是因为AliceSmith不在同一个嵌套对象中。

curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "White" }} 
          ]
        }
      },
      "inner_hits": { 
        "highlight": {
          "fields": {
            "user.first": {}
          }
        }
      }
    }
  }
}
'

说明

此查询得到匹配,是因为AliceWhite位于同一个嵌套对象中。

inner_hits允许我们突出显示匹配的嵌套文档。

输出

{
    "took": 6,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 1,
        "max_score": 1.987628,
        "hits": [
            {
                "_index": "my_index",
                "_type": "my_type",
                "_id": "1",
                "_score": 1.987628,
                "_source": {
                    "group": "fans",
                    "user": [
                        {
                            "first": "John",
                            "last": "Smith" },
                        {
                            "first": "Alice",
                            "last": "White" }
                    ]
                },
                "inner_hits": {
                    "user": {
                        "hits": { "total": 1, "max_score": 1.987628, "hits": [ { "_index": "my_index", "_type": "my_type", "_id": "1", "_nested": { "field": "user", "offset": 1 }, "_score": 1.987628, "_source": { "first": "Alice", "last": "White" }, "highlight": { "user.first": [ "<em>Alice</em>" ] } } ] } }
                }
            }
        ]
    }
}

嵌套文档可以:

3. 嵌套字段参数

嵌套字段接受以下参数:

参数 描述
dynamic 是否将新属性动态添加到现有的嵌套对象。共有true(默认),falsestrict三种参数。
include_in_all Sets the default include_in_all value for all the properties within the nested object. Nested documents do not have their own _all field. Instead, values are added to the _all field of the main “root” document.
properties 嵌套对象中的字段,可以是任何数据类型,包括嵌套。新的属性可能会添加到现有的嵌套对象。

备注

类型映射(type mapping)、对象字段和嵌套字段包含的子字段,称之为属性properties。这些属性可以为任意数据类型,包括object和 nested。属性可以通过以下方式加入:

  • 当在创建索引时显式定义他们。
  • 当使用PUT mapping API添加或更新映射类型时显式地定义他们。
  • 当索引包含新字段的文档时动态的加入。

重要

由于嵌套文档作为单独的文档进行索引,因此只能在nested查询,nested/reverse_nested聚合或者 nested inner hits 的范围内进行访问。

For instance, if a string field within a nested document has index_options set to offsets to allow use of the postings highlighter, these offsets will not be available during the main highlighting phase. Instead, highlighting needs to be performed via nested inner hits.

4. 限制嵌套字段的个数

索引一个拥有100个嵌套字段的文档,相当于索引了101个文档,因为每一个嵌套文档都被索引为一个独立的文档.为了防止不明确的映射,每个索引可以定义的嵌套字段的数量已被限制为50个。 具体请参阅 Settings to prevent mappings explosion

原文:https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html#nested-params

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
数据库 索引
elasticsearch中join类型数据如何进行父子文档查询?
elasticsearch中join类型数据如何进行父子文档查询?
|
4月前
|
自然语言处理 关系型数据库 数据库
ElasticSearch 映射类型及数据类型区分
ElasticSearch 映射类型及数据类型区分
53 0
|
5月前
|
JSON 搜索推荐 大数据
Elasticsearch:从 ES|QL 到 PHP 对象
【6月更文挑战第9天】Elasticsearch 是一款强大的开源搜索引擎,适用于大数据处理和分析。在 PHP 开发中,使用 ES|QL 构建复杂查询后,通常需将查询结果转换为 PHP 对象。通过 `json_decode()` 函数解析 JSON 数据,可以实现这一目标。示例代码展示了如何将 Elasticsearch 响应转换为 PHP 对象并遍历数据。这样,我们可以进一步处理和操作数据,适应不同项目需求。随着技术和方法的更新,不断学习和适应将提升我们在开发中的效率和创新力。
96 10
|
5月前
|
SQL 安全 数据挖掘
Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的?
Elasticsearch聚合查询用于复杂数据分析,包括统计空值率。示例展示了如何计算字段`my_field`非空非零文档的百分比。查询分为三步:总文档数计数、符合条件文档数计数及计算百分比。聚合概念涵盖度量、桶和管道聚合。脚本在聚合中用于动态计算。常见聚合类型如`sum`、`avg`、`date_histogram`等。组合使用可实现多值统计、嵌套聚合和空值率计算。[阅读更多](https://zhangfeidezhu.com/?p=515)
298 0
Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的?
|
5月前
|
存储 索引
Elasticsearch中父子文档的关联:利用Join类型赋予文档的层级关系
Elasticsearch中父子文档的关联:利用Join类型赋予文档的层级关系
|
5月前
|
存储 索引
Elasticsearch索引之嵌套类型:深度剖析与实战应用
Elasticsearch索引之嵌套类型:深度剖析与实战应用
|
6月前
|
搜索推荐 JavaScript Java
Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?
Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?
92 0
|
6月前
|
SQL 关系型数据库 数据库
实时计算 Flink版产品使用合集之将数据写入Elasticsearch时,若Elasticsearch中的字段类型为date,对应的SQL类型应该是什么
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
6月前
|
存储 SQL 运维
Elasticsearch 查询革新:探索 Wildcard 类型的高效模糊匹配策略
Elasticsearch 查询革新:探索 Wildcard 类型的高效模糊匹配策略
253 0
|
6月前
|
SQL JSON DataWorks
DataWorks产品使用合集之DataWorks 数据集成任务中,将数据同步到 Elasticsearch(ES)中,并指定 NESTED 字段中的 properties 类型如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
88 0
下一篇
无影云桌面