ElasticSearch系列--父子关系

其他网址

笔记四十三:文档的父子关系 | Elasticsearch 技术论坛
ElasticSearch7.2 父子文档 | 紫夜の博客

join类型--英文官网

简介

嵌套与父子的区别

嵌套(nested) 父子
优点

读取性能高。

(据官方:比父子快5-10倍)

父子文档可以独立更新
缺点 更新子文档时,需更新整个文档。

读取性能差。(需额外的内存去维护关系)

CPU占用率很高。

使用场景 查询为主,子文档偶尔更新。

子文档更新频繁

子文档经常查询

注意事项

  • 父子文档需要在同一分片上
  • 每个索引只能有一个join字段
  • 每个元素可以有多个子,但只有一个父
  • 可以为一个已存在的join字段添加新的关联关系
  • 可以在一个元素已经是父的情况下添加一个子

实例

需求

一篇博客,对应多个评论。  (本处以6.x示例,7.x基本一样的。)

设置Mapping

PUT my_blogs
{
    "settings": {
        "number_of_shards": 2
    },
    "mappings": {
        "blog": {
            "properties": {
                "blog_comments_relation": {
                    "type": "join",
                    "relations": {
                        "blog": "comment"
                    }
                },
                "content": {
                    "type": "text"
                },
                "title": {
                    "type": "keyword"
                }
            }
        }
    }
}

索引文档

索引父文档

PUT my_blogs/blog/blog1
{
  "title":"Learning Elasticsearch",
  "content":"learning ELK @ geektime",
  "blog_comments_relation":{
    "name":"blog"
  }
}
PUT my_blogs/blog/blog2
{
  "title":"Learning Hadoop",
  "content":"learning Hadoop",
    "blog_comments_relation":{
    "name":"blog"
  }
}

索引子文档

父文档和子文档必须存在相同的分片上。(确保查询 join 的性能)

当指定文档时候,必须指定它的父文档 ID。(使用 route 参数来保证,分配到相同的分片)

PUT my_blogs/blog/comment1?routing=blog1
{
  "comment":"I am learning ELK",
  "username":"Jack",
  "blog_comments_relation":{
    "name":"comment",
    "parent":"blog1"
  }
}
PUT my_blogs/blog/comment2?routing=blog2
{
  "comment":"I like Hadoop!!!!!",
  "username":"Jack",
  "blog_comments_relation":{
    "name":"comment",
    "parent":"blog2"
  }
}
PUT my_blogs/blog/comment3?routing=blog2
{
  "comment":"Hello Hadoop",
  "username":"Bob",
  "blog_comments_relation":{
    "name":"comment",
    "parent":"blog2"
  }
}

查询(通过parent_id)

通过对父文档 Id 进行查询,返回所有相关的子文档。

POST my_blogs/_search
{
    "query": {
        "parent_id": {
          "type": "comment",
          "id": "blog2"
        }
    }
}

结果

查询(通过has_child)

通过对子文档进行查询,返回具体相关子文档的父文档。父子文档在相同的分片上,因此 Join 效率高。

本处查询“Jack”评论过的博客。

POST my_blogs/_search
{
    "query": {
        "has_child": {
          "type": "comment",
          "query": {
            "match": {
              "username": "Jack"
            }
          }
        }
    }
}

 结果

查询(通过has_parent)

通过对父文档进行查询,返回相关的子文档。

本处查询名字为“Learning Hadoop”的博客的评论。

POST my_blogs/_search
{
    "query": {
        "has_parent": {
          "parent_type": "blog",
          "query": {
            "match": {
              "title": "Learning Hadoop"
            }
          }
        }
    }
}

 执行结果

访问子文档

通过ID访问子文档

访问comment1

GET my_blogs/blog/comment1?routing=blog1

结果(有数据) 

本处用下边语句会得到同样的结果,原因待查证。 

GET my_blogs/blog/comment1

访问comment2

GET my_blogs/blog/comment2

结果(没有数据)

 指定routing

GET my_blogs/blog/comment2?routing=blog2

结果(有数据)

 访问comment3

GET my_blogs/blog/comment3?routing=blog2

结果(有数据) 

 本处使用下边语句得到同样结果,原因待查证。

GET my_blogs/blog/comment3

更新子文档

更新子文档不会影响到父文档。

法1:POST _update

POST my_blogs/blog/comment3/_update?routing=blog2
{
  "doc": {
    "comment": "Hello Hadoop??"
  }
}

结果

 法2:PUT

PUT my_blogs/blog/comment3?routing=blog2
{
    "comment": "Hello Hadoop..",
    "blog_comments_relation": {
      "name": "comment",
      "parent": "blog2"
    }
}

结果

猜你喜欢

转载自blog.csdn.net/feiying0canglang/article/details/112001323