ES入门十:关系模型的实现:嵌套类型和父子文档-parent/child(父子类型)

时间:2024-03-17 16:11:40

join数据类型允许在一个索引中的文档创建父子关系,通过维护父子文档的关系独立出来两个对象。父文档和自文档是相互独立的,通过类似引用的关系进行绑定,所以当父文档更新时,不需要更新自文档,而自文档可以被任意的添加、修改、删除而不会影响到父文档和其他自文档

需要注意的是,为了维护父子文档的关系需要占用额外的内存资源,并且读取性能相对较差。但是由于父子文档是互相独立的,所以适合自文档更新频率高的场景

在Mapping中定义join数据类型
PUT join_books_index
{
  "mappings": {
    "properties": { 
      "book_id": { "type": "keyword" },
      "name": { "type": "text" },
      "book_comments_relation": { # 定义字段名字
        "type": "join", # 此字段为 join 类型
        "relations": { # 声明 Parent / Child 的关系
          "book": "comment" # book 是 Parent 的名称,comment 是 Child 的名称
        }
      }
    }
  },
  "settings": {
    "number_of_shards": 3, # 定义 3 个主分片
    "number_of_replicas": 1
  }
}

如上示例,book_comments_relation是字段的名字,使用join关键字定义此字段的类型为join类型,relations处声明了Parent/Child的关系,其中book是Parent的名称, comment是Child的名称

索引父文档(创建)

在定义了Mapping之后,我们写入父文档的数据

image.png

索引子文档(创建)

image.png
如上所示,book_comments_relation中声明了文档的类型为comment(即mapping中的自文档),并且使用parent字段指向父文档的id

为了确保查询时候的性能,父文档和子文档必须在同一个分片,所以需要强制使用routing参数,并且其值为父文档的Id(如果写入父文档的时候也用routing参数,那么需要保证他们的值是一样的)

数据检索

image.png
返回结果:
image.png

如图所示,我们在获取父文档的数据时候是不返回子文档的信息的,因为父子文档是相互独立的

获取子文档:
image.png
如上图所示,在获取子文档时,如果不加routing参数时,是无法找到对应的子文档的。routing参数的值为父文档的Id

parent id查询

image.png
如上所示,parent_id字段里面,我们查询了父文档Id为11并且comment类型的文档

返回结果:
image.png

has child查询

如果我们想查询用户“fork”评论了那些书本,可以使用 Has Child 查询。Has Child 查询将在子文档中进行条件匹配,然后返回匹配文档对应的父文档的信息
image.png
返回结果:
image.png

has parent查询

那如果我们想查询java相关书籍的评论时,可以使用Has Parent 查询。 Has Parent 查询会在父文档中进行匹配,然后返回匹配文档对应的子文档的信息。
image.png
返回结果:
image.png