天天看点

elasticsearch之文档的父子关系索引父文档

文档的父子关系

###Parent / Child

###● 对象和 Nested 对象的局限性

###● 每次更新,需要重新索引整个对象(包括根对象和嵌套对象)

###● ES 提供了类似关系型数据库中 Join 的实现。使⽤ Join 数据类型实现,可以通过维护 Parent

###/ Child 的关系,从⽽分离两个对象

###● ⽗⽂档和⼦⽂档是两个独⽴的⽂档

###● 更新⽗⽂档⽆需重新索引⼦⽂档。⼦⽂档被添加,更新或者删除也不会影响到⽗⽂档和其他的⼦⽂档

DELETE my_blogs

设置mapping

像指定其他属性一样。我们需要单独在映射关系中使用一个属性来指定我们的文档的父子关系,blog_comments_relation :父子关系的名字 使用join的type 来说明我们进行赋值关系的指定, 用relations 声明父子关系, “blog” 为父, “comment” 为子

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

索引父文档

通过name 来指定索引的是父文档还是子文档

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

#索引父文档
PUT my_blogs/_doc/blog2
{
  "title": "Learning Hadoop",
  "content": "learning Hadoop",
  "blog_comments_relation": {
    "name": "blog"
  }
}
           

索引子文档

单独指定子文档的id为comment1 通过指定routing ,确保子文档和父文档索引到相同的分片

在blog_comments_relation 关系字段中通过 name指定当前文档为子文档,通过parent 指定对应的父文档id

PUT my_blogs/_doc/comment1?routing=blog1
{
  "comment": "I am learning ELK",
  "username": "Jack",
  "blog_comments_relation": {
    "name": "comment",
    "parent": "blog1"
  }
}
#索引子文档
PUT my_blogs/_doc/comment2?routing=blog2
{
  "comment":"I like Hadoop!!!!!",
  "username":"Jack",
  "blog_comments_relation":{
    "name":"comment",
    "parent":"blog2"
  }
}

#索引子文档
PUT my_blogs/_doc/comment3?routing=blog2
{
  "comment":"Hello Hadoop",
  "username":"Bob",
  "blog_comments_relation":{
    "name":"comment",
    "parent":"blog2"
  }
}
           

##Parent / Child 所⽀持的查询

##● 查询所有⽂档

##● Parent Id 查询

##● Has Child 查询

##● Has Parent 查询

查询所有,可以通过blog_comments_relation 中的name属性看出数据为子文档还是父文档

POST my_blogs/_search

我们可以通过has_child 查询,返回具有相关子文档的父文档数据。因为父子文档在相同的分片上,所以join的效率很高

我们进行has_child查询, 并且指定当前文档为子文档 type。

child==》parent 孩子有哪些父亲

####查询名字为jack的子文档的父文档的数据

我们的父文档为 一些文章的标题 以及内容

我们的字文档为 作者名称

jack写了哪些文章

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

我们可以通过has_parent 查询,返回父文档相关的子文档数据

parent==>child 通过父 找到子 父亲有哪些孩子

parent_type 指定父文档类型

通过文章标题找到他的作者是谁

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

使用parent_id 查询,可以通过父文档的id 返回所有的孩子

type指定子文档的类型

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

直接查询父文档id 只能返回父文档的信息

GET my_blogs/_doc/blog2
           

因为子文档和父文档都是单独的数据存储,所以更新子文档不会影响到父文档

通过指定id/_update 进行更新,而不是全量替换,

通过routing 指定父文档id

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

POST my_blogs/_update/comment3?routing=blog2
{
  "doc":{
    "comment": "hello world!"
  }
}
           

##- https://www.elastic.co/guide/en/elasticsearch/reference/7.1/query-dsl-has-child-query.html

##- https://www.elastic.co/guide/en/elasticsearch/reference/7.1/query-dsl-has-parent-query.html

##- https://www.elastic.co/guide/en/elasticsearch/reference/7.1/query-dsl-parent-id-query.html

##- https://www.elastic.co/guide/en/elasticsearch/reference/7.1/query-dsl-parent-id-query.html

继续阅读