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
    }
  }
}















相关文章
|
6月前
|
JavaScript
写一个函数将N组<>(包含开始和结束),进行组合,并输出组合结果 (js)
写一个函数将N组<>(包含开始和结束),进行组合,并输出组合结果 (js)
95 0
|
Java
Java 对象间关系(依赖、关联、聚合和组合)
面向对象设计 对象间关系:依赖、关联、聚合和组合,四种关系容易混淆。特别后三种,只是在语义上有所区别,所谓语义就是指上下文环境、特定情景等。 
471 1
|
API Serverless 监控
函数组合的N种方式
随着以函数即服务(Function as a Service)为代表的无服务器计算(Serverless)的广泛使用,很多用户遇到了涉及多个函数的场景,需要组合多个函数来共同完成一个业务目标,这正是微服务“分而治之,合而用之”的精髓所在。
2338 0
|
5月前
|
存储 索引
Elasticsearch中父子文档的关联:利用Join类型赋予文档的层级关系
Elasticsearch中父子文档的关联:利用Join类型赋予文档的层级关系
|
6月前
|
存储 小程序 程序员
嵌套的方式构建
嵌套的方式构建
25 0
|
6月前
|
存储 JavaScript
如果需要在组件之间共享一个`ref`,应该如何实现?
如果需要在组件之间共享一个`ref`,应该如何实现?
74 0
|
JavaScript
Extjs中给一个组件命名时,id,name,hiddenName这三者的用法和区别是什么
Extjs中给一个组件命名时,id,name,hiddenName这三者的用法和区别是什么
|
存储
GreenPlum7聚合操作结构体之间关系
GreenPlum7聚合操作结构体之间关系
101 0
es聚合查询并且返回对应组的数据
es聚合查询并且返回对应组的数据
439 0
ts重点学习91-分布式条件类型
ts重点学习91-分布式条件类型
97 0
ts重点学习91-分布式条件类型