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 ...
随机推荐
- JAVA反序列化漏洞基础原理
JAVA反序列化漏洞基础原理 1.1 什么是序列化和反序列化? Java序列化是指把Java对象转换为字节序列的过程: Java反序列化是指把字节序列恢复为Java对象的过程: 1.2 为什么要序列化 ...
- 导出excel、word、csv文件方法汇总
http://www.woaic.com/2012/06/64 excel文件主要是输出html代码.以xls的文本格式保存文件. 生成excel格式的代码: /// <summary> ...
- 成本降低40%、资源利用率提高20%的 AI 应用产品云原生容器化之路
作者 郭云龙,腾讯云高级工程师,目前就职于 CSIG 云产品三部-AI 应用产品中心,现负责中心后台业务框架开发. 导语 为了满足 AI 能力在公有云 SaaS 场景下,服务和模型需要快速迭代交付的需 ...
- Jmeter系列(2)- 代理服务器录制脚本
操作步骤 step-1 添加代理服务器 step-2 添加线程组 step-3 添加录制控制器 HTTP代理服务器配置 - HTTP(S) Test Script Recorder TestPlan ...
- Ubuntu18.04 安装Tomcat 8.5
下载tomcat,登陆官网:https://tomcat.apache.org/ 点击tar.gz后,弹出这个不大懂这是什么? tomcat要求的jdk版本 解压tar包 sudo tar zxvf ...
- appium+python自动化:获取元素属性get_attribute
使用get_attribute()获取元素属性,括号里应该填写什么? 查看appium源码 如果是获取resource-id,填写resourceId self.driver.find_element ...
- Spring,AOP实现功能级别权限验证
1. 首先是问题出现的原因 对于一个我的一个个人博客网站,我希望游客可以浏览我的博客,但是评论功能是需要登录才能使用 这就需要对某个功能进行权限验证 对于过滤器,拦截器,AOP的区别日后再讨论,现在是 ...
- Monte-carlo-simulation
https://towardsdatascience.com/how-to-use-monte-carlo-simulation-to-help-decision-making-a0a164bc861 ...
- Dapr + .NET Core实战(十-终篇)K8S运行Dapr
工作原理 为了实现在k8s上安装Dapr,Dapr需要部署dapr-sidecar-injector.dapr-operator.dapr-placement和dapr-sentry服务. dapr- ...
- VUE -input输入框字母转大写
示例: 输入自动转--->大写 <input type="text" placeholder="请输入证件号码" maxlength="1 ...