当前位置: 首页 > article >正文

ElasticSearch-关联关系

  • Elasticsearch并不擅长处理关联关系,一般会采用以下四种方法处理关联
    • 对象类型
    • 嵌套对象 (Nested Object)
    • 父子关联关系 (Parent / Child)
    • 应用端关联

对象类型

  • 在每一博客的文档中都保留作者的信息
    • 如果作者信息发生变化,需要修改相关的博客文档
  • 包含对象数组的文档
    • 可能会搜到不需要的结果
      • 存储时,内部对象的边界并没有考虑在内,JSON格式被处理成扁平式键值对的结构
      • 当对多个字段进行查询时,导致意外的搜索结果
      • 可以用 Nested Data Type 解决这个问题
POST /my_movies/_doc/1 
{"title":"Speed","actors":[
  {"first_name":"Keanu","last_name":"Reeves"},
  {"first_name":"Dennis","last_name":"Hopper"}]}
# 会搜到不需要的结果,因为 JSON 格式被处理成扁平式键值对的结构
POST /my_movies/_search
{"query":{"bool":{"must":[
  {"match":{"actors.first_name":"Keanu"}}, 
  {"match":{"actors.last_name":"Hopper"}}]}}}

嵌套对象 (Nested Object)

  • Nested Data Type
    • Nested数据类型: 允许对象数组中的对象被独立索引
    • 使用nested 和properties 关键字,将所有actors索引到多个分隔的文档
    • 在内部, Nested文档会被保存在两个Lucene文档中,在查询时做Join处理
# 创建 Nested 对象 Mapping
PUT /my_movies
{"mappings":{"properties":{
  "actors":{"type":"nested","properties":{
    "first_name":{"type":"keyword"},
    "last_name":{"type":"keyword"}}},
  "title":{"type":"text",
    "fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}}
POST /my_movies/_doc/1 
{"title":"Speed","actors":[
  {"first_name":"Keanu","last_name":"Reeves"},
  {"first_name":"Dennis","last_name":"Hopper"}]}
# Nested 查询
POST /my_movies/_search
{"query":{"bool":{"must":[
  {"match":{"title": "Speed"}}, 
  {"nested":{"path":"actors","query":{"bool":{"must":[
    {"match":{"actors.first_name":"Keanu"}},
    {"match":{"actors.last_name":"Hopper"}}]}}}}]}}}
# Nested Aggregation
POST /my_movies/_search
{"size":0,"aggs":{"actors":{
  "nested":{"path":"actors"},
  "aggs":{"actor_name":{"terms":{
    "field":"actors.first_name","size":10}}}}}}
# 普通 aggregation 不工作
POST /my_movies/_search
{"size":0,"aggs":{
 "NAME":{"terms":{
   "field":"actors.first_name","size":10}}}}

父子关联关系 (Parent / Child)

  • 对象和Nested对象的局限性: 每次更新,可能需要重新索引整个对象 (包括根对象和嵌套对象)
  • ES提供了类似关系型数据库中Join 的实现
    • 使用Join数据类型实现,可以通过维护Parent/ Child的关系,从而分离两个对象
  • 父文档和子文档是两个独立的文档
  • 更新父文档无需重新索引子文档
  • 子文档被添加,更新或者删除也不会影响到父文档和其他的子文档
  • 注意
    • 父文档和子文档必须存在相同的分片上,能够确保查询 join 的性能
    • 当指定子文档时候,必须指定它的父文档ld。使用routing参数来保证,分配到相同的分片
# 设定 Parent/Child Mapping
PUT /my_blogs
{"settings":{"number_of_shards":2},
 "mappings":{"properties":{
   "blog_comments_relation":{"relations":{"blog":"comment"},
     "type":"join"},
   "content":{"type":"text"},
   "title":{"type":"keyword"}}}}
# 索引父文档
PUT /my_blogs/_doc/blog1
{"title":"Learning Elasticsearch", 
 "content":"learning ELK ",
 "blog_comments_relation":{"name":"blog"}}
# 索引子文档
PUT /my_blogs/_doc/comment1?routing=blog1 
{"comment":"I am learning ELK",
 "username":"Jack",
 "blog_comments_relation":{"name":"comment","parent":"blog1"}}
# Parent Id 查询
POST /my_blogs/_search 
{"query":{"parent_id":{"type":"comment","id":"blog2"}}}
# Has Child 查询, 返回父文档 
POST /my_blogs/_search
{"query":{"has_child":{
  "type":"comment","query":{"match":{"username":"Jack"}}}}}
# Has Parent 查询, 返回相关的子文档 
POST /my_blogs/_search
{"query":{"has_parent":{
  "parent_type":"blog","query":{"match":{"title":"Learning Hadoop"}}}}}
# 通过 ID, 访问子文档
GET /my_blogs/_doc/comment3
# 通过 ID 和 routing, 访问子文档
GET /my_blogs/_doc/comment3?routing=blog2
# 更新子文档
PUT /my_blogs/_doc/comment3?routing=blog2 
{"comment":"Hello Hadoop??",
 "blog_comments_relation":{"name":"comment","parent":"blog2"}}

嵌套文档 VS 父子文档

Nested ObjectParent / Child
优点文档存储在一起,读取性能高父子文档可以独立更新
缺点更新嵌套的子文档时,需要更新整个文档需要额外的内存维护关系,读取性能相对差
适用场景子文档偶尔更新,以查询为主子文档更新频繁

http://www.kler.cn/a/291608.html

相关文章:

  • Unity 6 Preview(预览版)新增功能
  • SAP抓取外部https报错SSL handshake处理方法
  • OpenHarmony-6.IPC/RPC组件
  • 拆解一个微型气泵了解工作原理
  • 禅说:zookeeper与聚落。
  • 2024年12月陪玩系统-仿东郊到家约玩系统是一种新兴的线上预约线下社交、陪伴系统分享-优雅草央千澈-附带搭建教程
  • Ruoyi若依框架中工单管理(智能售货机运营管理系统)
  • 前端知识HTMLCSS
  • 软件测试 - 性能测试 (概念)(并发数、吞吐量、响应时间、TPS、QPS、基准测试、并发测试、负载测试、压力测试、稳定性测试)
  • 浙大数据结构:01-复杂度2 Maximum Subsequence Sum
  • Spring Boot:医疗排班系统开发的技术革新
  • java 给list对象根据给定条数进行分组工具类
  • Ai Illustrator 取消吸附到像素点,鼠标拖动的时候只能到像素点
  • 如何给Maven添加阿里云镜像
  • union 的正确食用方法
  • 任务栏透明怎么设置?适配最新版 Windows 电脑的方法介绍(图文教程)
  • 【文献阅读】AdaLora: Adaptive Budget Allocation for Parameter-Efficient Fine-Tuning
  • 鸿蒙ndk
  • List 集合指定值升序降序排列Comparator实现
  • JVM系列(八) -运行期的几种优化技术
  • TikTok养号一般养几天?账号起步方法
  • 0.3 学习Stm32经历过的磨难
  • 深度学习系列69:tts技术原理
  • 使用matplotlab绘制多条形图
  • 四、材料与制造工艺 笔记
  • 微深节能 环冷机卸灰小车定位远程控制系统 格雷母线