ES中通过join类型字段构建父子关联

简介: ES中通过join类型字段构建父子关联

一、前言


ES中支持非常丰富的关联查询实现方式,本节主要介绍如何通过join类型字段,实现同索引中的父子关联查询。


二、Join field type


1、介绍

官网地址:Join field type

join类型的字段主要用来在同一个索引中构建父子关联关系。通过relations定义一组父子关系,每个关系都包含一个父级关系名称和一个子级关系名称。


示例:

创建索引my_index,并在mappings中指定关联字段my_join_field的type类型为join,

并通过relations属性指定关联关系,父级关系名称为question,子级关系名称为answer。

这里的父子级关系的名称可以自己定义,在向索引中添加数据时,需要根据定义的关系名称

指定my_join_field字段的值。

my_join_field关联字段的名称也可以自定义。

PUT my_index
{
  "mappings": {
      "properties": {
        "text":{"type": "keyword"},
        "my_join_field": { 
          "type": "join",
          "relations": {
            "question": "answer" 
          }
        }
      }
    }
}


注意⚠️:

Join字段不能像关系型数据库中的join使用,在ES中为了保证良好的查询性能,最佳的实践是将数据模型设置为非规范化文档,也就是通过字段冗余构造宽表。

针对每一个join字段,has_child 或 has_parent 查询都会对您的查询性能造成重大影响。


补充说明:

_parent字段类型已经被移除,被join字段代替。

74.png


2、适用场景

数据中包含明显的一对多的关系,且其中一个实体的数量明显超过另一个实体。

比如:产品和产品报价信息。在报价明显超过产品数量的情况下,将产品建模为父文档并将报价建模为子文档是有意义的。


3、相关限制

1、一个索引中只能包含一个join字段

2、父子文档必须在同一个分片中

3、一个文档可以有多个子文档,但是只能有一个父文档。

4、可以给一个存在的join字段添加一个新的关联关系。


三、数据准备


1、添加父级数据

说明:

添加父级数据在关联字段my_join_field中,需要指定name名称为question,声明在join关联中是父级对象。

PUT my_index/_doc/1?refresh
{
  "text": "我是第一个问题",
  "my_join_field": {
    "name": "question" 
  }
}
PUT my_index/_doc/2?refresh
{
  "text": "我是第二个问题",
  "my_join_field": {
    "name": "question"
  }
}

2、添加子级数据

说明:

添加子级数据时,在关联字段my_join_field中,需要指定name名称为answer,声明在join关联中是子级对象,同时在parent属性中指定父类id

并且在routing属性中指定父级数据的id,保证父子数据在索引的同一个分片中。


PUT my_index/_doc/3?routing=1&refresh 
{
  "text": "问题一的答案1",
  "my_join_field": {
    "name": "answer", 
    "parent": "1" 
  }
}
PUT my_index/_doc/4?routing=1&refresh
{
  "text": "问题一的答案2",
  "my_join_field": {
    "name": "answer",
    "parent": "1"
  }
}


四、关联查询


1、根据parent_id查询

说明:

parent_id查询只能根据父id查询子数据。

GET my_index/_search
{
  "query": {
    "parent_id": { 
      "type": "answer",
      "id": "1"
    }
  }
}


2、has_parent查询

说明:

has_parent用来查询满足条件的父类下的子数据

GET my_index/_search
{
  "query": {
    "has_parent": {
      "parent_type": "question",
      "query": {
        "term": {
          "text": {
            "value": "我是第一个问题"
          }
        }
      }
    }
  }
}


3、has_child查询

说明:

has_child用来根据子类条件查询满足条件的父类。

GET my_index/_search
{
  "query": {
    "has_child": {
      "type": "answer",
      "query": {
        "term": {
          "text": {
            "value": "问题一的答案2"
          }
        }
      }
    }
  }
}


五、多级关联


1、一父多子

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "my_join_field": {
        "type": "join",
        "relations": {
          "question": ["answer", "comment"]  
        }
      }
    }
  }
}


2、多层父子级

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "my_join_field": {
        "type": "join",
        "relations": {
          "question": ["answer", "comment"],  
          "answer": "vote" 
        }
      }
    }
  }
}


父子关系图:

73.png

注意⚠️:

实际使用中尽量避免使用多级关联。不但数据难于管理维护,查询性能也会非常地下。


总结:

本文主要介绍了在ES中如何通过join类型字段构建父子关联关系。

1、如何通过join字段在同一个索引中构建数据间的父子关联。

2、父子索引数据必须保证在同一分片中。

3、适用场景:数据中包含明显的一对多的关系。

4、父级可以有多个子级,但是一个子级只能对应一个父级。

5、has_child 或 has_parent 查询的使用

目录
相关文章
|
Java Spring
spring data elasticsearch: 设置保活策略|长时间不连接es,报错超时连接
java client长时间没有连接es后,再次调用访问接口,报错连接超时
2310 0
|
设计模式 JSON 架构师
你真的需要防腐层吗?DDD 系统间的7种关系梳理与实践
当提到系统间交互的时候,人们都会想到大名鼎鼎的防腐层,用来防止其他系统的模型变更对本系统造成影响。但是在实践这个模式的过程中,我们常常会遇到问题。此时我们也应该考虑下其他的系统交互方式。
27685 12
你真的需要防腐层吗?DDD 系统间的7种关系梳理与实践
|
7月前
|
XML JSON API
掌握 Postman:高级 GET 请求技术与响应分析
本指南详细讲解了如何在 Postman 中发送 GET 请求并解析 API 响应,帮助开发者提升 API 测试与开发能力。Postman 是一款强大的工具,可简化请求发送和响应分析流程,并支持团队协作及多版本管理。通过创建集合、配置请求参数、设置身份验证与请求头等步骤,开发者能够高效测试 API。同时,理解响应体、Cookie、响应头等内容有助于深入分析 API 行为,确保高质量的软件交付。掌握 Postman 不仅提高效率,还能加深对 Web 通信机制的理解。
|
存储 安全 Linux
Podman入门全指南:安装、配置与运行容器
Podman入门全指南:安装、配置与运行容器
8041 1
|
关系型数据库 API Apache
Flink CDC:基于 Apache Flink 的流式数据集成框架
本文整理自阿里云 Flink SQL 团队研发工程师于喜千(yux)在 SECon 全球软件工程技术大会中数据集成专场沙龙的分享。
20181 11
Flink CDC:基于 Apache Flink 的流式数据集成框架
|
11月前
|
存储 Kubernetes 调度
深入理解Kubernetes中的Pod与Container
深入理解Kubernetes中的Pod与Container
603 0
|
数据处理 索引 Python
Pandas中的filter函数:有点鸡肋
Pandas中的filter函数:有点鸡肋
316 1
|
SQL Oracle 关系型数据库
Hive:Error while compiling statement: FAILED: ParseException cannot recognize input near '<EOF>' '<
Hive:Error while compiling statement: FAILED: ParseException cannot recognize input near '<EOF>' '<
Hive:Error while compiling statement: FAILED: ParseException cannot recognize input near '<EOF>' '<
|
存储 关系型数据库 MySQL
MySQL 索引优化:深入探索自适应哈希索引的奥秘
MySQL 索引优化:深入探索自适应哈希索引的奥秘