gulimall-商城业务-商品上架

news2024/11/25 6:34:47

商城业务

  • 前言
  • 一、商品上架
    • 1.1 商品 Mapping
    • 1.2 商品信息保存到es
    • 1.3 es数组的扁平化处理
    • 1.4 构造基本数据

前言

本文继续记录B站谷粒商城项目视频 P128-135 的内容,做到知识点的梳理和总结的作用,接口文档地址:gulimall接口文档

一、商品上架

上架的商品才可以在网站展示及被检索。

1.1 商品 Mapping

分析:商品上架在 es 中是存 sku 还是 spu?
1)检索的时候输入名字,是需要按照 sku 的 title 进行全文检索的。
2)检索使用商品规格,规格是 spu 的公共属性,每个 spu 是一样的。
3)按照分类 id 进去的都是直接列出 spu 的,还可以切换。
4)我们如果将 sku 的全量信息保存到 es 中(包括 spu 属性)就太多量字段了。
5)我们如果将 spu 以及他包含的 sku 信息保存到 es 中,也可以方便检索。但是 sku 属于 spu 的级联对象,在 es 中需要 nested 模型,这种性能差点。
6)但是存储与检索我们必须性能折中。
7)如果我们分拆存储,spu 和 attr 一个索引,sku 单独一个索引可能涉及的问题。

检索商品的名字,如“手机”,对应的 spu 有很多,我们要分析出这些 spu 的所有关联属性,再做一次查询,就必须将所有 spu_id 都发出去。假设有 1 万个数据,数据传输一次就 10000*4 = 4MB;并发情况下假设 1000 检索请求,那就是 4GB 的数据,,传输阻塞时间会很长,业务更加无法继续。

所以,我们如下设计,这样才是文档区别于关系型数据库的地方,宽表设计,不能去考虑数据库范式。

1.2 商品信息保存到es

PUT product
{
  "mappings": {
    "properties": {
      "skuId": {
        "type": "long"
      },
      "spuId": {
        "type": "keyword"
      },
      "skuTitle": {
        "type": "text",
        "analyzer": "ik_smart"
      },
      "skuPrice": {
        "type": "keyword"
      },
      "skuImg": {
        "type": "keyword",
        "index": false,
        "doc_values": false
      },
      "saleCount": {
        "type": "long"
      },
      "hasStock": {
        "type": "boolean"
      },
      "hotScore": {
        "type": "long"
      },
      "brandId": {
        "type": "long"
      },
      "catalogId": {
        "type": "long"
      },
      "brandName": {
        "type": "keyword",
        "index": false,
        "doc_values": false
      },
      "brandImg": {
        "type": "keyword",
        "index": false,
        "doc_values": false
      },
      "catalogName": {
        "type": "keyword",
        "index": false,
        "doc_values": false
      },
      "attrs": {
        "type": "nested",
        "properties": {
          "attrId": {
            "type": "long"
          },
          "attrName": {
            "type": "keyword",
            "index": false,
            "doc_values": false
          },
          "attrValue": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

index:
默认 true,如果为 false,表示该字段不会被索引,但是检索结果里面有,但字段本身不能当做检索条件。
doc_values:
默认 true,设置为 false,表示不可以做排序、聚合以及脚本操作,这样更节省磁盘空间。
还可以通过设定 doc_values 为 true,index 为 false 来让字段不能被搜索但可以用于排序、聚
合以及脚本操作。

1.3 es数组的扁平化处理

在这里插入图片描述
只需要修改 user 的类型即可:

PUT my-index
{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested"
      }
    }
  }
}

执行查询操作,返回0条数据。

1.4 构造基本数据

商品上架接口: POST /product/spuinfo/{spuId}/up

SpuInfoController 层代码

/**
 * 商品上架
 * @param spuId
 * @return
 */
@PostMapping("/{spuId}/up")
public R spuUp(@PathVariable Long spuId){
    spuInfoService.productUp(spuId);

    return R.ok();
}

sku 在 es 存储的数据

@Data
public class SkuEsModel {

    private Long skuId;

    private Long spuId;

    private String skuTitle;

    private BigDecimal skuPrice;

    private String skuImg;

    private Long saleCount;

    private Boolean hasStock;

    private Long hotScore;

    private Long brandId;

    private Long catalogId;

    private String brandName;

    private String brandImg;

    private String catalogName;

    private List<Attrs> attrs;


    @Data
    public static class Attrs {
        private Long attrId;
        private String attrName;
        private String attrValue;
    }

}

业务层代码

@Override
public void productUp(Long spuId) {
    //1.查出当前spuId对应的所有sku信息,品牌的名字
    List<SkuInfoEntity> skus = skuInfoService.getSkusBySpuId(spuId);

    List<Long> skuIdList = skus.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());

    //TODO 4.查询当前sku的所有可以被检索的规格属性
    List<ProductAttrValueEntity> baseAttrs = attrValueService.baseAttrListForSpu(spuId);
    List<Long> attrIds = baseAttrs.stream().map(attrValue -> {
        return attrValue.getAttrId();
    }).collect(Collectors.toList());

    List<Long> searchAttrIds = attrService.selectSearchAttrs(attrIds);
    Set<Long> ids = new HashSet<>(searchAttrIds);

    List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().filter(item -> {
        return ids.contains(item.getAttrId());
    }).map(item -> {
        SkuEsModel.Attrs attr = new SkuEsModel.Attrs();
        BeanUtils.copyProperties(item, attr);
        return attr;
    }).collect(Collectors.toList());


    List<SkuEsModel> collect = skus.stream().map(sku -> {
        // 组装存储到es的数据
        SkuEsModel skuEsModel = new SkuEsModel();
        BeanUtils.copyProperties(sku, skuEsModel);
        skuEsModel.setSkuPrice(sku.getPrice());
        skuEsModel.setSkuImg(sku.getSkuDefaultImg());

        //TODO 2.热度评分 0
        skuEsModel.setHotScore(0L);

        //TODO 3.查询品牌和分类信息
        BrandEntity brand = brandService.getById(sku.getBrandId());
        skuEsModel.setBrandName(brand.getName());
        skuEsModel.setBrandImg(brand.getLogo());

        CategoryEntity category = categoryService.getById(sku.getCatalogId());
        skuEsModel.setCatalogName(category.getName());

        //设置检索属性
        skuEsModel.setAttrs(attrsList);

        return skuEsModel;
    }).collect(Collectors.toList());

    //TODO 5.将数据发送给es进行保存 gulimall-search

    //TODO 1.发送远程调用,库存系统是否有库存
    R skusHasStock = wareFeignService.getSkusHasStock(skuIdList);
    //2.封装每个sku的信息
}

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

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

相关文章

面了个字节拿 30K 出来的测试,让我见识到了什么是测试的天花板

人人都有大厂梦&#xff0c;对于软件测试人员来说&#xff0c;BATJ 为首的一线互联网公司肯定是自己的心仪对象&#xff0c;毕竟能到这些大厂工作&#xff0c;不仅薪资高待遇好&#xff0c;而且能力技术都能够得到提升&#xff0c;最关键的是还能够给自己镀上一层金&#xff0c…

jenkins pipline 拉取git历史版本

声明&#xff0c;本文是基于&#xff1a;jenkins流水线&#xff08;jenkinsfile&#xff09;详解&#xff0c;保姆式教程_我认不到你的博客-CSDN博客&#xff0c;以下内容介绍通过 Commit ID 拉取 git 历史版本 Commit ID &#xff08;节点号&#xff09;是什么&#xff1f;&a…

5G配电网专用工业级路由器(电力紧凑型DTU)-智慧电力物联网

随着近年来智能电网的快速发展&#xff0c;它实现了电力系统的监控、数据、电能的统一化智能管理&#xff0c;通过与5G技术结合&#xff0c;助力构建高可靠、高灵活、高效率的配电网络。 5G网络技术具备低时延传输的特点&#xff0c;满足配电网安全、控制的苛刻要求&#xff0…

软件测试面试一定要准备的7个高频面试题(附答案,建议收藏)

收集了很多人在面试时的面试题后&#xff0c;我特意整理出了7个高频出现的面试题&#xff0c;一起来看看。 高频问题1&#xff1a;请自我介绍下&#xff1f; 高频问题2&#xff1a;请介绍下最近做过的项目&#xff1f; 高频问题3&#xff1a;请介绍下你印象深刻的bug&#xff1…

Android网络握手失败问题分析

问题场景 调用某功能云端接口请求&#xff0c;保存如下信息&#xff1a;Web服务通信期间握手期间远程主机关闭连接 javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake分析 由于同一份代码不同机器有的能调用成功&#xff0c;有的调用失…

C#通用的二进制转化为float和double方法

上一篇&#xff0c;我们将32位二进制【或4个字节】转化为float【Real】小数&#xff0c;这次我们使用通用的方法进行二进制转化。 C#中将32位二进制转换为float【Real】十进制类型_斯内科的博客-CSDN博客 二进制转化float(double)方法: //单精度浮点数对应32位 /…

挖出电商店铺详情数据-API接口分享

在今天的互联网时代&#xff0c;电商平台已经成为了我们生活中不可或缺的一部分。淘宝作为全国最大的电商平台之一&#xff0c;其商品信息也越来越丰富&#xff0c;但是如果你想开发一款能够帮助用户购物的应用程序&#xff0c;就必须获取到淘宝的API接口&#xff0c;才能让你的…

【Webpack】前端工程自动化 - require.context实现模块自动化导入

一、介绍 require.context 是基于 webpack 的一个的 api&#xff0c;主要用来实现模块的自动化导入在前端工程中&#xff0c;如果遇到一个文件需要引入很多模块的情况&#xff0c;可以使用这个apirequire.context 会遍历文件夹中的指定文件&#xff0c;然后自动导入&#xff0…

记一次redis主从切换导致的数据丢失与陷入只读状态故障

背景 最近一组业务redis数据不断增长需要扩容内存&#xff0c;而扩容内存则需要重启云主机&#xff0c;在按计划扩容升级执行主从切换时意外发生了数据丢失与master进入只读状态的故障&#xff0c;这里记录分享一下。 业务redis高可用架构 该组业务redis使用的是一主一从&am…

从“0”到“1”!低代码开发和云计算的碰撞,引领数字化转型浪潮!

随着互联网技术的飞速发展&#xff0c;数字化转型已经成为企业转型升级的必经之路。而在数字化转型的过程中&#xff0c;云计算和低代码开发逐渐成为新技术的代表&#xff0c;为企业提供更高效、更灵活的技术支持&#xff0c;让企业赢得更大的竞争优势。 云计算的发展 云计算是…

三阶段项目

DHCP分配不到冲突地址 需要重启 再分配 用这个命令 reset ip pool name vlan40 all ospf&#xff1a; 建立邻居表&#xff1a;报文&#xff1a;hello报文 状态&#xff1a;down int 2-way 选举DR 同步数据库&#xff1a;报文&#xff1a;DD-LSR-LSU-LSACK 状态&#xff…

C语言-printf打印%*s、%.*s与%-.*s的区别

一、简介 在平时的使用中&#xff0c;会经常使用到printf进行打印&#xff0c;而最长使用的方式是printf("%s",string)进行打印。但是有个问题&#xff0c;如果string结尾不是0。那么printf会继续打印&#xff0c;直到遇到0为止。这样就会有内存溢出的风险。显然&…

(三)ArcGIS空间数据的转换与处理——栅格数据变换

ArcGIS空间数据的转换与处理——栅格数据变换 目录 ArcGIS空间数据的转换与处理——栅格数据变换 1.地理配准2.平移3.扭曲4.旋转5.翻转6.重设比例尺7.镜像 数据变换是指对数据进行诸如放大、缩小、翻转、移动、扭曲等几何位置、形状和方位的改变等操作。对于 栅格数据的相应操…

类和对象 - 练习题(C++)

目录 1、求123...n 题目链接&#xff1a; 题目&#xff1a; 题目描述&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 2 计算日期到天数转换 题目链接&#xff1a; 题目&#xff1a; 题目描述&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 3 日期差值 题目链接&…

人工智能学习07--pytorch18--目标检测:Faster RCNN源码解析(pytorch)

参考博客&#xff1a; https://blog.csdn.net/weixin_46676835/article/details/130175898 VOC2012 1、代码的使用 查看pytorch中的faster-rcnn源码&#xff1a; 在pytorch中导入&#xff1a; import torchvision.models.detection.faster_rcnn即可找到faster rcnn所实现的源…

NIFI分页获取Postgresql数据到Hbase中_实际操作---大数据之Nifi工作笔记0049

首先看一下整体流程,可以看到这里用的PutHbaseJson处理器,把数据导入到 hbase中的 注意这里也可以使用PutSql导入数据,通过phoenix的jdbc驱动,然后把数据利用PutSql处理器导入到 Hbase中,但是我这里的时候报错了,然后一直没解决,所以最后用了PutHbaseJson处理器,把数据存入到…

【LinuxShell】linux防火墙之SNAT策略和DNAT策略

文章目录 前言一、SANT策略1.SNAT策略概述2.SNAT的典型应用环境3.SNAT的工作原理4.SNAT策略的应用SNAT转换前提条件SNAT策略打开方式SNAT实验过程 5.知识扩展 二、DNAT策略1.DNAT策略概述2.DNAT的典型应用环境3.DNAT的工作原理4.DNAT策略的应用DNAT转换前提条件DNAT地址转换方式…

linux管道通信原理

管道&#xff0c;通常指无名管道&#xff0c;是 UNIX 系统IPC&#xff08;InterProcess Communication)最古老的形式。 1、特点: 1.它是半双工的(即数据只能在一个方向上流动) &#xff0c;具有固定的读端和写端 2.它只能用于具有亲缘关系的进程之间的通信(也是子进程或者兄弟进…

python 读写 json,csv,txt,docx,xlsx,xls文件大全

目录 前言一、读写json1.1 读1.2 写1.2.1 list类型写入1.2.2 dict类型写入 二、读写csv2.1 读2.2 写2.2.1 list类型写入2.2.2 dict类型写入 三、读写txt3.1 读3.2 写按行写入&#xff08;手动添加换行符\n&#xff09;按行写入&#xff08;python添加换行符\n&#xff09;3.2.1…