Elasticsearch实战(二十四)---ES数据建模一对多模型Nested结构

news/2024/7/5 4:55:57

Elasticsearch实战—ES数据建模一对多模型Nested结构

文章目录

    • Elasticsearch实战---ES数据建模一对多模型Nested结构
      • 1.ES 一对多模型Nested 结构模型实战
      • 2.ES字段查询
        • 2.1 非Nested 错误结构及错误查询
        • 2.2 Nested结构,正确查询
      • 3.Nested结构原理

我们如何把Mysql的模型合理的在ES中去实现? 就需要你对要存储的数据足够的了解,及对应用场景足够的深入分析,才能建立一个合适的模型,便于你后期扩展

  1. 一对一 模型
  2. 一对多 模型
  3. 多对多 模型

上一篇,我们介绍了 一对多模型,采用Object对象存储的巨大缺陷,本篇文章,我们给出解决办法 就是采用Nested结构来存储数据, 但是Nested查询和读写需要有特定的语法,也就是一定程度上增加了读写的复杂性,但是数据的查询结果是正确的,所以说Nested 才是我们一对多 推荐的一种设计模型

1.ES 一对多模型Nested 结构模型实战

我们采用下面创建Index mapping结构,和上一篇大致一样的结构,把多个手机相同的分类信息,作为冗余字段 冗余到 手机基本信息中

差别就是 : 这次category字段,我们采用Nested结构,而不是Object结构,通过关键字 type:nested 来实现

索引库结构

PUT /phone_nested_index
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 2
  },
  "mappings": {
    "properties": {
      "productId": {
        "type": "long"
      },
      "productName": {
        "type": "keyword"
      },
      "productPrice": {
        "type": "long"
      },
      "productNumber": {
        "type": "long"
      },
      "category": {
        "type": "nested", 
        "properties": {
          "categoryName": {
            "type": "keyword"
          },
          "categoryRemark": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

同样的,插入数据, 下面我们给 phone_index 索引库插入数据, 插入 6条手机信息

put /phone_nested_index/_bulk
{"index":{"_id":1}}
{"productId":1,"productName":"P20","productPrice":4000,"productNumber":50,"category":{"categoryName":"华为手机","categoryRemark":"高端"}}
{"index":{"_id":2}}
{"productId":2,"productName":"Honor30","productPrice":2000,"productNumber":100,"category":[{"categoryName":"华为手机","categoryRemark":"很好"},{"categoryName":"荣耀手机","categoryRemark":"便宜"}]}
{"index":{"_id":3}}
{"productId":3,"productName":"小米8","productPrice":2000,"productNumber":600,"category":{"categoryName":"小米手机","categoryRemark":"中端"}}
{"index":{"_id":4}}
{"productId":4,"productName":"红米10","productPrice":2500,"productNumber":300,"category":{"categoryName":"小米手机","categoryRemark":"发烧"}}
{"index":{"_id":5}}
{"productId":5,"productName":"小米Max","productPrice":4000,"productNumber":800,"category":{"categoryName":"小米手机","categoryRemark":"很好"}}

2.ES字段查询

我们要查询 华为手机 便宜的 标签,must 查询, 分类:华为手机,描述:便宜

Nested结构查询,需要特定的语法,需要加上查询路径,我们的就是 path:category 信息

2.1 非Nested 错误结构及错误查询

老的结构 非Nested phone_index 数据

get /phone_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "category.categoryName": "华为手机"
          }
        },
        {
          "match": {
            "category.categoryRemark": "便宜"
          }
        }
      ]
    }
  }
}

查询结果 不是我们想要的, 是错误的
在这里插入图片描述

或者 我们再查询以下 华为手机-发烧的 场景, 按照我们的数据, 不存在任何数据把华为手机和发烧关联

must查询, 分类:华为手机, 标签:发烧

get /phone_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "category.categoryName": "华为手机"
          }
        },
        {
          "match": {
            "category.categoryRemark": "发烧"
          }
        }
      ]
    }
  }
}

查询结果错误, 要查询 华为手机-发烧的数据,结果把 小米手机查询出来了,这是明显的错误
在这里插入图片描述

2.2 Nested结构,正确查询

同样,我们采用Nested结构查询, 查询华为手机 且便宜的 信息
Nested结构查询,需要带上查询条件 path路径信息 “nested”: {“path”: “category”}

get /phone_nested_index/_search
{
  "query": {
    "nested": {
      "path": "category",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "category.categoryName": "华为手机"
              }
            },
            {
              "match": {
                "category.categoryRemark": "便宜"
              }
            }
          ]
        }
      }
    }
  }
}

查询结果, 符合预期,并没有查询出 错误的结果, 查询结果为空
在这里插入图片描述
现在我们来查以下另一种场景, 华为手机-发烧 的查询语句,看看是否能够正确查询

get /phone_nested_index/_search
{
  "query": {
    "nested": {
      "path": "category",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "category.categoryName": "华为手机"
              }
            },
            {
              "match": {
                "category.categoryRemark": "发烧"
              }
            }
          ]
        }
      }
    }
  }
}

同样的结果,查询结果没有数据, 也是符合我们预期的,是正确的查询结果
在这里插入图片描述

3.Nested结构原理

上面我们验证了采用Nested 结构,可以有效的解决 object对象存储, 错误的查询方式这种缺陷,那么原理是什么呢?

官方定义:官方释义:

  • nested属于object类型的一种,是Elasticsearch中用于复杂类型对象数组的索引操作。Elasticsearch没有内部对象的概念
  • ES在存储复杂类型的时候会把对象的复杂层次结果扁平化为一个键值对列表,
  • 说明白点就是 把搜索条件指定到一个独立Object对象中,把搜索的条件指定到数组中某一个特定 object 数据中, 而不是分散在整个数组中
  • 虽然读写操作复杂了,但是 查询结果是正确的,这是我们一对多 推荐的一种设计模型

这样就可以解决Object对象存储的问题


http://lihuaxi.xjx100.cn/news/1305217.html

相关文章

初步学习使用SpringBoot框架

对于SpringBoot框架介绍大家可以看看这个这篇文章,SpringBoot优缺点以及如何安装使用 以下我是按照老师给的安装方法进行安装使用SpringBoot框架: 大家安装SpringBoot框架时候,最好安装3.0以下的,不然需要对应较高版本的JDK版本&…

快速排序的三路划分方法和归并排序的递归和非递归实现

目录 快速排序的三路划分方法 归并排序的递归实现 归并排序的非递归实现 快速排序的三路划分方法 首先快排的时间复杂度为O(N*logN),空间复杂度O(logN),不稳定。 三路划分:将数据分为三份;可以提高当数据中出现多个重复数字时的效率。 …

有没有免费提取音频的软件,分享几个给大家!

在日常生活中,我们经常遇到需要从视频中提取音频的情况,无论是为了制作音频片段、录制语音笔记还是进行后期编辑。本文将介绍三种免费提取音频的方法,分别是记灵在线工具、PR(Adobe Premiere Pro)和剪映。通过这些方法…

【新版系统架构】第九章-软件可靠性基础知识

软考-系统架构设计师知识点提炼-系统架构设计师教程(第2版) 第一章-绪论第二章-计算机系统基础知识(一)第二章-计算机系统基础知识(二)第三章-信息系统基础知识第四章-信息安全技术基础知识第五章-软件工程…

基于Springboot+mybatis+mysql+vue实现企业注册模块功能

基于Springbootmybatismysqlvue实现企业注册模块功能 一、系统介绍二、功能展示1.主页面2.注册成功 三、数据库四、代码展示四、其他系统实现五、获取源码 一、系统介绍 该系统实现简单的企业信息注册,保存后,提示注册成功。 运行环境:idea…

哈希表--day6--总结篇

文章目录 数组作为哈希表set作为哈希表map作为哈希表 一般来说哈希表都是用来快速判断一个元素是否出现集合里。 对于哈希表,要知道哈希函数和哈希碰撞在哈希表中的作用. 哈希函数是把传入的key映射到符号表的索引上。 哈希碰撞处理有多个key映射到相同索引上时的…

unity制作游戏,点击鼠标左键,展示屏幕震动效果

在Unity中实现点击鼠标左键展示屏幕震动效果可以通过以下步骤进行: 创建一个新的C#脚本,例如"ScreenShake.cs",并将其附加到想要添加屏幕震动效果的游戏对象上。 在脚本中定义一个变量来控制震动的幅度,例如public flo…

运输层概述、端口号、复用与分用

1.运输层概述、端口号、复用与分用 笔记来源: 湖科大教书匠:运输层概述 湖科大教书匠:运输层端口号、复用与分用的概念 声明:该学习笔记来自湖科大教书匠,笔记仅做学习参考 1.1 运输层概述 计算机网络体系结构中的物…