ES中 Nested 类型的原理和使用

简介: ES中 Nested 类型的原理和使用

1、Nested(嵌套类型)是个啥?

官方定义:官方释义:这个nested类型是object一种数据类型,允许对象数组以相互独立的方式进行索引


nested属于object类型的一种,是Elasticsearch中用于复杂类型对象数组的索引操作。Elasticsearch没有内部对象的概念,因此,ES在存储复杂类型的时候会把对象的复杂层次结果扁平化为一个键值对列表。


2、适用场景

字段值为复杂类型的情况,即字段值为非基本数据类型


3、案例

3.1 场景

假如我们有如下order索引,包含订单的商品列表

PUT /order/_doc/1
{
  "order_name": "xiaomi order",
  "desc": "shouji zhong de zhandouji",
  "goods_count": 3,
  "total_price": 12699,
  "goods_list": [
    {
      "name": "xiaomi PRO MAX 5G",
      "price": 4999
    },
    {
      "name": "ganghuamo",
      "price": 19
    },
    {
      "name": "shoujike",
      "price": 1999
    }
  ]
}
PUT /order/_doc/2
{
  "order_name": "Cleaning robot order",
  "desc": "shouji zhong de zhandouji",
  "goods_count": 2,
  "total_price": 12699,
  "goods_list": [
    {
      "name": "xiaomi cleaning robot order",
      "price": 1999
    },
    {
      "name": "dishwasher",
      "price": 4999
    }
  ]
}


3.2 需求

查询订单商品中商品名称为dishwasher并且商品价格为1999的订单信息,尝试执行以下脚本

GET order/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "goods_list.name": "dishwasher"    // 条件一
          }
        },
        {
          "match": {
            "goods_list.price": 1999           // 条件二
          }
        }
      ]
    }
  }
}


3.3 结果

按照bool中must的查询逻辑,两个条件都符合的数据并不存在,然而执行查询后发现返回以下结果

"hits" : [
      {
        "_index" : "order",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.7199211,
        "_source" : {
          "order_name" : "Cleaning robot order",
          "desc" : "shouji zhong de zhandouji",
          "goods_count" : 2,
          "total_price" : 12699,
          "goods_list" : [
            {
              "name" : "xiaomi cleaning robot order",
              "price" : 1999
            },
            {
              "name" : "dishwasher",
              "price" : 4999
            }
          ]
        }
      }
    ]


3.4 原因分析

可以看到上述结果元数据中出现了订单数据,这和预期结果不一致。

分析原因如下:

当字段值为复杂数据类型(Object、Geo-Point等)的时候,ES内部实际是以如下方式保存数据的:

{
  "order_name": "Cleaning robot order",
  "desc": "shouji zhong de zhandouji",
  "goods_count": 2,
  "total_price": 12699,
  "goods_list.name":[ "alice", "cleaning", "robot", "order", "dishwasher" ],
  "goods_list.price":[ 1999, 4999 ]
}

上述例子中goods_list中每个对象元素的属性值被扁平化存储在了数组中,此时已丢失了对应关系,因此无法保证搜索的准确。


3.5 解决方案

使用Nested类型


4、Nested用法

上述问题解决办法即对复杂类型使用Nested类型。在ES中嵌套类型不止Nested一种,但是只有Nested是单独的考点,因此其他的暂不需考虑


4.1 创建Mapping

在Mapping中为复杂类型指定Nested类型

PUT order
{
  "mappings": {
    "properties": {
      "goods_list": {
        "type": "nested",
        "properties": {
          "name": {
            "type": "text"
          }
        }
      }
    }
  }
}


4.2 写入数据

再次写入数据,此处省去此步骤代码。


4.3

执行查询,实际为query外层进行了一层嵌套。

GET /order/_search
{
  "query": {
    "nested": {
      "path": "goods_list", 
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "goods_list.name": "dishwasher"
              }
            },
            {
              "match": {
                "goods_list.price": 4999
              }
            }
          ]
        }
      }
    }
  }
}


相关文章
|
API 索引
JDK8之findAny和findFirst
JDK8之findAny和findFirst
614 0
|
搜索推荐 Java 应用服务中间件
【Maven】IDEA部署配置Maven项目教程,IDEA配置Tomcat(2019.3.3)(2023.1.3)
当涉及到软件开发和项目管理时,使用一个可靠的构建工具是非常重要的。Maven是一个广泛使用的构建工具,它为Java项目提供了一种简化的构建过程和依赖管理。 在本文中,我们将探讨如何部署Maven并开始使用它来构建您的项目。我们将介绍所需的步骤,并向您提供一些有用的提示和建议。
【Maven】IDEA部署配置Maven项目教程,IDEA配置Tomcat(2019.3.3)(2023.1.3)
|
存储 索引
Elasticsearch索引之嵌套类型:深度剖析与实战应用
Elasticsearch索引之嵌套类型:深度剖析与实战应用
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
464 1
|
存储 SQL API
Flink教程(23)- Flink高级特性(Streaming File Sink)
Flink教程(23)- Flink高级特性(Streaming File Sink)
1132 0
|
9月前
|
存储 算法 NoSQL
千亿级向量索引的秘密武器:一文详解蚂蚁集团的工程实践和开源突破
本文整理自2025QCon全球软件大会贾玮(蚂蚁集团NoSQL数据库和向量数据库的技术负责人)的演讲实录。 本文围绕向量检索技术的研究与实践展开系统性阐述,包含以下四个维度: 1.向量检索的基础原理以及相关的核心技术挑战; 2.蚂蚁集团在向量检索领域的工程实践和具体案例; 3.向量检索领域的最新学术研究和应用成果; 4.蚂蚁开源向量索引库VSAG的最新进展。
|
SQL 存储 人工智能
Flink 在蚂蚁实时特征平台的深度应用
本文整理自蚂蚁集团高级技术专家赵亮星云,在 Flink Forward Asia 2023 AI 特征工程专场的分享。
2495 3
Flink 在蚂蚁实时特征平台的深度应用
|
存储 自然语言处理 关系型数据库
Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别
【7月更文挑战第3天】Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别
|
消息中间件 Kafka API
Kafka Exactly Once 语义实现原理:幂等性与事务消息
Apache Kafka的Exactly-Once语义确保了消息处理的准确性和一致性。通过幂等性和事务消息,Kafka实现了要么全处理要么全不处理的原子性。文章详细解析了Kafka事务的工作流程,包括生产者的幂等性(通过序列号保证),以及事务消息的提交和回滚过程。Kafka事务提供了ACID保证,但存在性能限制,如额外的RPC请求和单生产者只能执行一个事务。此外,事务适用于同集群内的操作,跨集群时原子性无法保证。了解这些原理有助于开发者更好地利用Kafka事务构建可靠的数据处理系统。
718 3
 Kafka Exactly Once 语义实现原理:幂等性与事务消息
|
存储 Java 编译器
【Java异常】Variable used in lambda expression should be final or effectively final
【Java异常】Variable used in lambda expression should be final or effectively final
668 0