Elasticsearch学习-父子文档

news2024/11/17 8:50:03

elasticsearch父子文档处理 join

  • 一、背景
  • 二、需求
  • 三、前置知识
  • 四、实现步骤
    • 1、创建 mapping
    • 2、添加父文档数据
    • 3、添加子文档
    • 4、查询文档
      • 1、根据父文档id查询它下方的子文档
      • 2、has_child返回满足条件的父文档
      • 3、has_parent返回满足父文档的子文档
  • 五、Nested Object 和 join 对比
  • 六、参考文档

一、背景

在我们工作的过程中,有些时候我们需要用到父子文档的关系映射。**比如:**一个问题有多个答案、一本书籍有多个评论等等。此处我们可以使用 es 的 jion数据类型或 nested来实现。此处我们使用join来建立es中的父子文档关系。

二、需求

我们需要创建一个计划(plan),计划下存在活动(activity)和书籍(book),书籍下存在评论(comments)。

即层级结构为:

     plan
    /    \
   /      \
activity  book
           |
           |
          comments
1234567

三、前置知识

  1. 每一个mapping下只能有一个join类型的字段。
  2. 父文档和子文档必须在同一个分片(shard)上。即: 增删改查一个子文档都必须和父文档使用相同的 routing key。
  3. 每个元素只能有一个父,但是可以存在多个子。
  4. 可以为一个已经存在的 join 字段增加新的关联关系。
  5. 可以为一个已经是父的元素增加一个子元素。

join数据类型在elasticsearch中不应该像关系型数据库那种使用。而且has_childhas_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"
        }
      }
    }
  }
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061

注意⚠️

父子关系映射

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"
}
12345678910111213141516171819

注意⚠️:

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"
  }
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566

注意⚠️:

子文档的创建

1、子文档(子孙文档等)需要和父文档使用相同的路由键。

2、需要指定父文档的id。

3、需要指定join的名字。

4、查询文档

1、根据父文档id查询它下方的子文档

**需求:**返回父文档id是plan-001下的类型为book的所有子文档。

GET /plan_index/_search
{
  "query":{
    "parent_id": {
      "type":"book",
      "id":"plan-001"
    }
  }
}
123456789

根据父文档id查询子文档

2、has_child返回满足条件的父文档

**需求:**返回创建者(creator)是huan.fu,并且子文档最少有2个的父文档。

GET /plan_index/_search
{
  "query": {
    "has_child": {
      "type": "book",
      "min_children": 2,  
      "query": {
        "match": {
          "creator": "huan.fu"
        }
      }
    }
  }
}
1234567891011121314

has_child返回满足条件的父文档

3、has_parent返回满足父文档的子文档

**需求:**返回父文档(book)的创建者是huan.fu的所有子文档

GET /plan_index/_search
{
  "query": {
    "has_parent": {
      "parent_type": "book",
      "query": {
        "match": {
          "creator":"huan.fu"
        }
      }
    }
  }
}
12345678910111213

has_parent返回满足父文档的子文档

五、Nested Object 和 join 对比

Nested Objectjoin (Parent/Child)
1、文档存储在一起,读取性能高1、父子文档单独存储,互不影响。但是为了维护join的关系,需要占用额外的内容,读取性能略差。
2、更新父文档或子文档时,需要更新整个文档。2、父文档和子文档可以单独更新。
3、适用于查询频繁,子文档偶尔更新的情况。3、适用于更新频繁的情况,且子文档的数量远远超过父文档的数量。

六、参考文档

1、join数据类型

2、has child查询

3、has parent查询

4、parent id查询

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/192569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker部署vue

1: 创建 Dockerfile 文件 配置一下内容: # 设置基础镜像,这里使用最新的nginx镜像,前面已经拉取过了 FROM nginx # 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面 COPY dist/ /usr/share/nginx/html/ 2: 安装nginx …

物联网平台的产品架构

一、物联网介绍1. 概述物联网( IoT ,Internet of things )即“万物相连的互联网”,是互联网基础上的延伸和扩展的网络,将各种信息传感设备与互联网结合起来而形成的一个巨大网络,实现在任何时间、任何地点&…

LeetCode 热题 HOT 100 -- Java 题解

LeetCode 热题 HOT 100 --Java 题解1. 两数之和2. 两数相加3. 无重复字符的最长子串4. 寻找两个正序数组的中位数1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下…

【信管10.3】风险定量分析及应对监控

风险定量分析及应对监控通过前三个过程,我们已经有了风险登记册,也就是一个所有识别出来的风险情况。然后可以通过定性风险分析来进行分类和排序。接下来我们要继续通过定量,也就是数据的手段来继续完善风险登记册。只有有了详尽的风险登记册…

我对KMP算法的简单理解

我对KMP算法的简单理解 前言:字符串匹配问题 问题概述: “字符串A是否为字符串B的子串?如果是,出现在B的什么位置?”这个问题就是字符串匹配问题。字符串A称为模式串(zs),字符串B称为主串(ss)。 其中&a…

C++ 深入理解模板实现多态思想

文章目录前言一、模板与多态基础1.模板2.多态二、模板实现多态三、实际应用前言 对C/C学习感兴趣的可以看看这篇文章噢:C/C教程 最近有时间,便用WTL写了一个兼具群聊、单聊以及传输文件的聊天软件,过几天应该就能更新到 C/C教程系列 中了 …

EasyGBS+EasyNVS技术方案,如何实现对多现场国标视频平台的统一管理?

一、平台能力 1)EasyGBS EasyGBS国标视频云服务平台支持无缝、完整接入内网或者公网的国标设备,在输出上,实现全平台、全终端输出。EasyGBS可将GB/T28181设备/平台推送的PS流转成ES流,并提供RTSP、RTMP、FLV、HLS、WebRTC等多种…

使用shell进行简单操作

目录 1、shell实现乘法表的打印 2、shell判定成绩等级 3、循环创建用户 1、shell实现乘法表的打印 要求:嵌套循环实现9*9乘法表(两种方式) 创建脚本文件:vim mcl.sh #!/bin/bash ######################### #File name:mcl.s…

idea插件及插件使用方法

CamelCase (下划线转驼峰) 使用快捷键:altshiftu。 按住altshift再不停的按U,会把选中内容的单词的下划线转驼峰转大写等,不停的转换。 Maven Helper Maven助手 安装之后再次打开pom文件,文件左下角会多出一个视图。 切换到"…

软件测试基础(三) 之 软件的生命周期

软件的生命周期一、软件的生命周期简述软件的生命周期中最早可能是客户,可能是产品的一个想法阶段,然后再到后来的一个需求阶段,再到开发人员去进行编码,去进行自己的自测,再提到软件测试人员进行综合测试,…

C语言之初识指针

前言 🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言初阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:介绍c语言中的新知识—指针有关的知识. 金句分享: ✨知…

大数据舆情监控流程,TOOM大数据舆情监控范围

大数据舆情监控是一种通过大数据技术,分析社会舆情信息,掌握舆情动态的方法。它利用大数据的存储和处理能力,对海量的网络舆情数据进行收集、清洗、分析、呈现,帮助企业和机构了解公众的想法和评价,掌握舆情动态&#…

【正点原子FPGA连载】第三十一章Linux内核定时器实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Linux开发指南

1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692450874670 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第三十一章Linux…

【Linux】多线程详解(中)

🎇Linux: 博客主页:一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话: 看似不起波澜的日复一日,一定会在某一天让你看见坚持…

哈希表的概念(散列表)

一、基本概念 散列表特点 : 数据元素的关键字与存储地址直接相关 通过哈希函数建立“关键字”与“存储地址”的联系 若不同的关键字通过散列函数映射到同一个值,则称它们为 “同义词” 通过散列函数确定的位置已经存放了其他元素,则称这种…

今日题目分享(两个维度的思考,双指针/动态规划,b站视频讲解)

先直接上连接 941有效的山脉数组 845数组中的最长山脉 2100适合打劫银行的日子. 2420找到所有好下标. 什么是两个维度? 这里是从代码随想录里面学习到的思考方式,开门见山地说,就是两个方面去考虑题目,比如,要求第…

vue前端框架应用案例(二)实现简单的SPA应用

目录路由使用步骤案例效果案例目录结构App.vueAbout.vueHome.vueindex.jsmain.jsindex.html本博客参考尚硅谷官方课程,详细请参考 【尚硅谷bilibili官方】 本博客以vue2作为学习目标(请勿混淆v2与v3的代码规范,否则可能出现报错&#xff09…

docker搭建nacos集群

一、先搭建MySQL主从模式 Nacos使用delby作为内嵌数据库,在使用集群作为部署方式时,内嵌数据库无法保持数据同步与数据一致,故一般使用外接MySQL数据库的方式保存配置文件。使用一主一从的方式搭建,实现主从复制与读写分离。 1.…

线缆也可能是静电危害的罪魁祸首?

众所周知,几乎所有的电子元器件都是对静电敏感的,如果处理不当,将恶化元器件的性能,甚至造成彻底损坏。在低温干燥的环境中,极易产生静电,当然静电主要还是通过摩擦产生的。除了我们所熟知的静电产生的原因…

史上最全的测试用例设计方法

目录 前言 等价类划分方法: 边界值分析方法: 错误推测方法 因果图方法 判定表驱动分析方法 总结 前言 今天还是给大家带来一些干货,总结了一下测试用例的设计方法。具体内容太多我总结成了文档,获取方法在文末。这里截取部…