ES父子级关系Join类型的使用

简介: ES父子级关系Join类型的使用

1、基本概念

连接数据类型是一个特殊字段,它在同一索引的文档中创建父/子关系。关系部分在文档中定义了一组可能的关系,每个关系是一个父名和一个子名。父/子关系可以定义如下

PUT <index_name>
{
  "mappings": {
    "properties": {
      "<join_field_name>": { 
        "type": "join",
        "relations": {
          "<parent_name>": "<child_name>" 
        }
      }
    }
  }
}


2、使用场景

join类型不能像关系数据库中的表链接那样去用,不论是has_child或者是has_parent查询都会对索引的查询性能有严重的负面影响。并且会触发global ordinals


join唯一合适应用场景是:当索引数据包含一对多的关系,并且其中一个实体的数量远远超过另一个的时候。比如:老师一万个学生


3、注意事项

注意

在索引父子级关系数据的时候必须传入routing参数,即指定把数据存入哪个分片,因为父文档和子文档必须在同一个分片上,因此,在获取、删除或更新子文档时需要提供相同的路由值。

每个索引只允许有一个join类型的字段映射

一个元素可以有多个子元素但只有一个父元素

可以向现有连接字段添加新关系

也可以向现有元素添加子元素,但前提是该元素已经是父元素


4、案例

数据

# 部门
PUT depart
{
  "mappings": {
    "properties": {
      "msb_join_field": {
        "type": "join",
        "relations": {
          "depart": "employee"
        }
      },
      "my_id": {
        "type": "keyword"
      }
    }
  }
}
PUT depart/_doc/1
{
  "my_id": 1,
  "name":"教学部",
  "msb_join_field":{
    "name":"depart"
  }
}
PUT depart/_doc/2
{
  "my_id": 2,
  "name":"咨询部",
  "msb_join_field":{
    "name":"depart"
  }
}
# 老师 
# 路由值是强制性的,因为父文档和子文档必须在同一个分片上建立索引
PUT depart/_doc/3?routing=1&refresh
{
  "my_id": 3,
  "name":"吴老师",
  "msb_join_field":{
    "name":"employee",
    "parent":1
  }
}
PUT depart/_doc/4?routing=1&refresh
{
  "my_id": 4,
  "name":"周老师",
  "msb_join_field":{
    "name":"employee",
    "parent":1
  }
}
# 咨询
PUT depart/_doc/5?routing=1&refresh
{
  "my_id": 5,
  "name":"依依老师",
  "msb_join_field":{
    "name":"employee",
    "parent":2
  }
}
PUT depart/_doc/6?routing=1&refresh
{
  "my_id": 6,
  "name":"球球老师",
  "msb_join_field":{
    "name":"employee",
    "parent":2
  }
}
PUT depart/_doc/7?routing=1&refresh
{
  "my_id": 7,
  "name":"琪琪老师",
  "msb_join_field":{
    "name":"employee",
    "parent":2
  }
}


搜索所有部门

GET depart/_search
{
  "query": {
    "has_child": {
      "type": "employee",
      "query": {
        "match_all": {}
      }
    }
  }
}


搜索周老师所在部门

GET depart/_search
{
  "query": {
    "has_child": {
      "type": "employee",
      "query": {
        "match": {
          "name.keyword": "周老师"
        }
      }
    }
  }
}


搜索咨询部所有老师

GET depart/_search
{
  "query": {
    "has_parent": {
      "parent_type": "depart",
      "query": {
        "match": {
          "name.keyword": "咨询部"
        }
      }
    }
  }
}


搜索部门id为 2 的部门员工

GET depart/_search
{
  "query": {
    "parent_id":{
      "type":"employee",
      "id":2
    }
  }
}















相关文章
|
Java
Java 对象间关系(依赖、关联、聚合和组合)
面向对象设计 对象间关系:依赖、关联、聚合和组合,四种关系容易混淆。特别后三种,只是在语义上有所区别,所谓语义就是指上下文环境、特定情景等。 
541 1
获取两个list中相互不包含的部分
获取两个list中相互不包含的部分
152 0
|
API Serverless 监控
函数组合的N种方式
随着以函数即服务(Function as a Service)为代表的无服务器计算(Serverless)的广泛使用,很多用户遇到了涉及多个函数的场景,需要组合多个函数来共同完成一个业务目标,这正是微服务“分而治之,合而用之”的精髓所在。
2355 0
|
2月前
|
Python
通过 type 和 object 之间的关联,进一步分析类型对象
通过 type 和 object 之间的关联,进一步分析类型对象
59 3
|
6月前
|
存储 索引
Elasticsearch中父子文档的关联:利用Join类型赋予文档的层级关系
Elasticsearch中父子文档的关联:利用Join类型赋予文档的层级关系
|
7月前
|
存储 小程序 程序员
嵌套的方式构建
嵌套的方式构建
29 0
|
7月前
|
存储 JavaScript
如果需要在组件之间共享一个`ref`,应该如何实现?
如果需要在组件之间共享一个`ref`,应该如何实现?
84 0
|
存储
GreenPlum7聚合操作结构体之间关系
GreenPlum7聚合操作结构体之间关系
102 0
|
数据可视化 索引
Elastic:使用自定义属性来定义冷热节点时,为什么用include来声明路由时索引无法流转,而用require可以?
ILM中各节点的路由配置要和索引模版中的索引的路由配置方式保持一致:如果ILM中使用的是require,那么索引模版中也要使用require;如果ILM中使用的是include,那么索引模版中也要使用include。
80 0
Elastic:使用自定义属性来定义冷热节点时,为什么用include来声明路由时索引无法流转,而用require可以?