elasticsearch父子文档处理(join)
elasticsearch父子文档处理 join
一、背景
在我们工作的过程中,有些时候我们需要用到父子文档的关系映射。**比如:**一个问题有多个答案、一本书籍有多个评论等等。此处我们可以使用 es 的 jion数据类型或 nested来实现。此处我们使用join来建立es中的父子文档关系。
二、需求
我们需要创建一个计划(plan),计划下存在活动(activity)和书籍(book),书籍下存在评论(comments)。
即层级结构为:
plan
/ \
/ \
activity book
|
|
comments
三、前置知识
- 每一个
mapping下只能有一个join类型的字段。 - 父文档和子文档必须在同一个分片(
shard)上。即: 增删改查一个子文档都必须和父文档使用相同的 routing key。 - 每个元素只能有一个父,但是可以存在多个子。
- 可以为一个已经存在的 join 字段增加新的关联关系。
- 可以为一个已经是父的元素增加一个子元素。
join数据类型在elasticsearch中不应该像关系型数据库那种使用。而且has_child和has_parent都是比较消耗性能的。只有当 子的数据 远远大于 父的数据时,使用
join才是有意义的。比如:一个博客下,有多个评论。
四、实现步骤
1、创建 mapping
PUT /plan_index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"plan_id":{
"type": "keyword"
},
"plan_name":{
"type": "text",
"fields": {
"keyword":{
"type" : "keyword",
"ignore_above" : 256
}
}
},
"act_id":{
"type": "keyword"
},
"act_name":{
"type": "text",
"fields": {
"keyword":{
"type" : "keyword",
"ignore_above" : 256
}
}
},
"comment_id":{
"type": "keyword"
},
"comment_name":{
"type": "text",
"fields": {
"keyword":{
"type" : "keyword",
"ignore_above" : 256
}
}
},
"creator":{
"type": "keyword"
},
"create_time":{
"type": "date",
"format": "yyyy-MM-dd||yyyy-MM-dd HH:mm:ss"
},
"plan_join": {
"type": "join",
"relations": {
"plan": ["activity", "book"],
"book": "comments"
}
}
}
}
}
注意️

2、添加父文档数据
此处添加的是 (plan) 数据。
PUT /plan_index/_doc/plan-001
{
"plan_id": "plan-001",
"plan_name": "四月计划",
"creator": "huan",
"create_time": "2021-04-07 16:27:30",
"plan_join": {
"name": "plan"
}
}
PUT /plan_index/_doc/plan-002
{
"plan_id": "plan-002",
"plan_name": "五月计划",
"creator": "huan",
"create_time": "2021-05-07 16:27:30",
"plan_join": "plan"
}
注意️:
1、如果是创建父文档,则需要使用 plan_join 指定父文档的关系的名字(此处为plan)。
2、plan_join为创建索引的 mapping时指定join的字段的名字。
3、指定父文档时,plan_join的这2种写法都可以。
3、添加子文档
PUT /plan_index/_doc/act-001?routing=plan-001
{
"act_id":"act-001",
"act_name":"四月第一个活动",
"creator":"huan.fu",
"plan_join":{
"name":"activity",
"parent":"plan-001"
}
}
PUT /plan_index/_doc/book-001?routing=plan-001
{
"book_id":"book-001",
"book_name":"四月读取的第一本书",
"creator":"huan.fu",
"plan_join":{
"name":"book",
"parent":"plan-001"
}
}
PUT /plan_index/_doc/book-002?routing=plan-001
{
"book_id":"book-002",
"book_name":"编程珠玑",
"creator":"huan.fu",
"plan_join":{
"name":"book",
"parent":"plan-001"
}
}
PUT /plan_index/_doc/book-003?routing=plan-002
{
"book_id":"book-003",
"book_name":"java编程思想",
"creator":"huan.fu",
"plan_join":{
"name":"book",
"parent":"plan-002"
}
}
# 理论上 comment 的父文档是 book ,但是此处routing使用 plan 也是可以的。
PUT /plan_index/_doc/comment-001?routing=plan-001
{
"comment_id":"comment-001",
"comment_name":"这本书还可以",
"creator":"huan.fu",
"plan_join":{
"name":"comments",
"parent":"book-001"
}
}
PUT /plan_index/_doc/comment-002?routing=plan-001
{
"comment_id":"comment-002",
"comment_name":"值得一读,棒。",
"creator":"huan.fu",
"plan_join":{
"name":"comments",
"parent":"book-001"
}
}
注意️:

1、子文档(子孙文档等)需要和父文档使用相同的路由键。
2、需要指定父文档的id。
3、需要指定join的名字。
4、查询文档
1、根据父文档id查询它下方的子文档
**需求:**返回父文档id是plan-001下的类型为book的所有子文档。
GET /plan_index/_search
{
"query":{
"parent_id": {
"type":"book",
"id":"plan-001"
}
}
}

2、has_child返回满足条件的父文档
**需求:**返回创建者(creator)是huan.fu,并且子文档最少有2个的父文档。
GET /plan_index/_search
{
"query": {
"has_child": {
"type": "book",
"min_children": 2,
"query": {
"match": {
"creator": "huan.fu"
}
}
}
}
}

3、has_parent返回满足父文档的子文档
**需求:**返回父文档(book)的创建者是huan.fu的所有子文档
GET /plan_index/_search
{
"query": {
"has_parent": {
"parent_type": "book",
"query": {
"match": {
"creator":"huan.fu"
}
}
}
}
}

五、Nested Object 和 join 对比
| Nested Object | join (Parent/Child) |
|---|---|
| 1、文档存储在一起,读取性能高 | 1、父子文档单独存储,互不影响。但是为了维护join的关系,需要占用额外的内容,读取性能略差。 |
| 2、更新父文档或子文档时,需要更新整个文档。 | 2、父文档和子文档可以单独更新。 |
| 3、适用于查询频繁,子文档偶尔更新的情况。 | 3、适用于更新频繁的情况,且子文档的数量远远超过父文档的数量。 |
六、参考文档
1、join数据类型
elasticsearch父子文档处理(join)的更多相关文章
- elasticsearch 父子文档(十一)
说明 需求 一个产品多个区域销售 每个区域有自己的价格, 方式1冗余行,a 产品分别在 area1 area2 area3区域销售 a产品就会生成3条产品数据 搜索id去重就行了,但是问题就是 聚合 ...
- elasticsearch——海量文档高性能索引系统
elasticsearch elasticsearch是一个高性能高扩展性的索引系统,底层基于apache lucene. 可结合kibana工具进行可视化. 概念: index 索引: 类似SQL中 ...
- ES 父子文档查询
父子文档的特点 1. 父/子文档是完全独立的. 2. 父文档更新不会影响子文档. 3. 子文档更新不会影响父文档或者其它子文档. 父子文档的映射与索引 1. 父子关系 type 的建立必须在索引新建或 ...
- elasticsearch 路由文档到分片
路由文档到分片 当你索引一个文档,它被存储在单独一个主分片上.Elasticsearch是如何知道文档属于哪个分片的呢?当你创建一个新文档,它是如何知道是应该存储在分片1还是分片2上的呢? 进程不能是 ...
- ElasticSearch部署文档(Ubuntu 14.04)
ElasticSearch部署文档(Ubuntu 14.04) 参考链接 https://www.elastic.co/guide/en/elasticsearch/guide/current/hea ...
- ElasticSearch——原始文档和倒排索引
一.原始文档 如上图所示, 第二象限是一份原始文档,有title和content2个字段,字段取值分别为”我是中国人”和” 热爱共X产党”,这一点没什么可解释的.我们把原始文档写入Elasticsea ...
- 007-elasticsearch5.4.3【一】概述、Elasticsearch 访问方式、Elasticsearch 面向文档、常用概念
一.概述 Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene™ 基础之上. Elasticsearch 也是使用 Java 编写的,它的内部使用 L ...
- Elasticsearch 删除文档
章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...
- Elasticsearch 更新文档
章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...
随机推荐
- TCP协议中的TIME_WAIT详细说明
文章目录 4.3设置TIME_WAIT状态的目的 4.3.1 实现TCP全双工连接的关闭 4.3.2 使过时的重复报文段失效 4.3.3 TIME_WAIT状态的自结束 4.3.4 TIME_WAIT ...
- Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!
前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增.删.改.查的功能.JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现 ...
- Vue设置全局cookies样式
''' 配置全局cookies样式 下载:cnpm install vue-cookies import cookies from 'vue-cookies' Vue.prototype.$cooki ...
- 【PHP数据结构】图的遍历:深度优先与广度优先
在上一篇文章中,我们学习完了图的相关的存储结构,也就是 邻接矩阵 和 邻接表 .它们分别就代表了最典型的 顺序存储 和 链式存储 两种类型.既然数据结构有了,那么我们接下来当然就是学习对这些数据结构的 ...
- 使用metaweblog API实现通用博客发布 之 版本控制
使用metaweblog API实现通用博客发布 之 版本控制 接上一篇本地图片自动上传以及替换路径,继续解决使用API发布博客的版本控制问题. 当本地文档修订更新以后,如何发现版本更新,并自动发布到 ...
- 创建一个新的解耦的Orchard Core CMS网站
引言本文将介绍创建一个功能齐全.解耦的CMS网站的过程,该网站允许您编辑博客帖子并呈现它们.解耦是一种开发模型,其中站点的前端和后端(管理)托管在同一个Web应用程序中,但只有后端由CMS驱动.然后, ...
- Jmeter系列(19)- 常用配置文件
JMeter.properties :跟Jmeter配置相关的配置信息都在这边,比如:Jmeter GUI页面的语言.日志级别设置等 User.properties:用户自定义相关的所有变量,会复写J ...
- Vue 初学
Vue 的基本代码: 概念简介:Vue.js 是目前最火的一个前端框架,只关注视图层,主要负责MVC中的V这一层 MVC 是后端的分层开发概念: MVVM是前端视图层的概念, ...
- 彻底关闭Windows自动更新
win+r--输入services.msc(服务管理窗口)停止windows update服务并禁用同时在恢复里,改为无操作 win + r --输入gpedit.msc(本地组策略编辑器)家庭版没有 ...
- P4338-[ZJOI2018]历史【LCT】
正题 题目链接:https://www.luogu.com.cn/problem/P4338 题目大意 给出\(n\)个点的一棵树,和每个点进行\(access\)的次数\(a_i\),要求安排一个顺 ...