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

如果喜欢作者的文章,就点赞支持一下吧 O(∩_∩)O~
欢迎点击下方二维码关注作者