一:商品上架

  • 上架的商品才可以在网站展示。
  • 上架的商品需要可以被检索。
  • es是将数据保存到内存当中,所以我们不能将什么数据都保存到es当中,我们需要将重要的数据保存到es中。例如商品名称,规格型号,价格等信息。当需要的数据较多时,我们可以将主键id存储到es中,然后通过id再去mysql数据库中查询。并且es中存储的的都是json数据。

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 的数据,,传输阻塞时间会很 长,业务更加无法继续。 所以,我们如下设计,这样才是文档区别于关系型数据库的地方,宽表设计,不能去考虑数 据库范式。

PUT product
## product 的 mapping
{"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 来让字段不能被搜索但可以用于排序、聚 合以及脚本操作:

2.编写上架功能

1)在spuInfoController中添加方法

 /*** 商品上架功能* @param spuId* @return*/@RequestMapping("/{spuId}/up")//@RequiresPermissions("product:spuinfo:list")public R spuUp(@PathVariable("spuId") Long spuId) {spuInfoService.up(spuId);return R.ok();}

2)在common添加SkuEsModel 实体类,表示sku在es中保存的数据模型

package com.sysg.common.to.es;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@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;@Datapublic static class Attrs {private Long attrId;private String attrName;private String attrValue;}
}

3)编写SpuInfoServiceImpl的up方法

 @Overridepublic void up(Long spuId) {//1.查出当前spuId对应的所有sku信息,品牌的名字List<SkuInfoEntity> skus =  skuInfoService.getSkusBySpuId(spuId);//todo 4.查询sku的所有可以被用来检索的规格属性List<ProductAttrValueEntity> baseAttrs = productAttrValueService.baseAttrListforspu(spuId);List<Long> attrIds = baseAttrs.stream().map(attr -> {return attr.getAttrId();}).collect(Collectors.toList());List<Long> searchAttrIds = attrService.selectSearchAttrIds(attrIds);Set<Long> isSet = new HashSet<>(searchAttrIds);List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().filter(item -> {return isSet.contains(item.getAttrId());}).map(item -> {SkuEsModel.Attrs attrs1 = new SkuEsModel.Attrs();BeanUtils.copyProperties(item, attrs1);return attrs1;}).collect(Collectors.toList());//2.封装每个sku的信息List<SkuEsModel> collect = skus.stream().map((sku) -> {//组装需要的数据SkuEsModel esModel = new SkuEsModel();BeanUtils.copyProperties(sku,esModel);esModel.setSkuPrice(sku.getPrice());esModel.setSkuImg(sku.getSkuDefaultImg());//todo 1.发送远程调用,库存系统查询是否有库存//todo 2.热度评分。0esModel.setHotScore(0L);//todo 3.查询品牌和分类的名字信息BrandEntity brandEntity = brandService.getById(esModel.getBrandId());esModel.setBrandName(brandEntity.getName());esModel.setBrandImg(brandEntity.getLogo());CategoryEntity categoryEntity = categoryService.getById(esModel.getCatalogId());esModel.setCatalogName(categoryEntity.getName());//设置检索属性esModel.setAttrs(attrsList);return esModel;}).collect(Collectors.toList());//todo 5.将数据发送给es进行保存。发送给gulimail-search}

4)远程调用

  • 加入openFeign依赖
        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
  • 开启远程调用功能
@EnableFeignClients(basePackages = "com.sysg.gulimail.product.feign")
  • 在feign包下新建WareFeignService,用来远程调用ware相关操作
@FeignClient("gulimail-ware")
public interface WareFeignService {/*** 1.R可以加上泛型* 2.直接返回想要的数据* 3.自己封装* @param skuIds* @return*/@PostMapping("/ware/waresku/hasstock")R<List<SkuHasStockVo>> getSkusHasStock(@RequestBody List<Long> skuIds);
}
  • 代码实现
@Overridepublic void up(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 = productAttrValueService.baseAttrListforspu(spuId);List<Long> attrIds = baseAttrs.stream().map(attr -> {return attr.getAttrId();}).collect(Collectors.toList());List<Long> searchAttrIds = attrService.selectSearchAttrIds(attrIds);Set<Long> isSet = new HashSet<>(searchAttrIds);List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().filter(item -> {return isSet.contains(item.getAttrId());}).map(item -> {SkuEsModel.Attrs attrs1 = new SkuEsModel.Attrs();BeanUtils.copyProperties(item, attrs1);return attrs1;}).collect(Collectors.toList());//todo 1.发送远程调用,库存系统查询是否有库存Map<Long, Boolean> stockMap = null;try {R<List<SkuHasStockVo>> skusHasStock = wareFeignService.getSkusHasStock(skuIdList);stockMap = skusHasStock.getData().stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));} catch (Exception e) {log.error("库存服务查询异常:原因{}",e);}//2.封装每个sku的信息Map<Long, Boolean> finalStockMap = stockMap;List<SkuEsModel> uoProducts= skus.stream().map((sku) -> {//组装需要的数据SkuEsModel esModel = new SkuEsModel();BeanUtils.copyProperties(sku,esModel);esModel.setSkuPrice(sku.getPrice());esModel.setSkuImg(sku.getSkuDefaultImg());//设置库存信息if( finalStockMap ==null){esModel.setHasStock(true);} else {esModel.setHasStock(finalStockMap.get(sku.getSkuId()));}//todo 2.热度评分。0esModel.setHotScore(0L);//todo 3.查询品牌和分类的名字信息BrandEntity brandEntity = brandService.getById(esModel.getBrandId());esModel.setBrandName(brandEntity.getName());esModel.setBrandImg(brandEntity.getLogo());CategoryEntity categoryEntity = categoryService.getById(esModel.getCatalogId());esModel.setCatalogName(categoryEntity.getName());//设置检索属性esModel.setAttrs(attrsList);return esModel;}).collect(Collectors.toList());//todo 5.将数据发送给es进行保存。发送给gulimail-search}

注:远程调用需要抛出异常
5)将数据发送到es进行保存

//todo 5.将数据发送给es进行保存。发送给gulimail-searchtry {R r = searchFeignService.productStatusUp(uoProducts);if(r.getCode() == 0){//远程调用成功//todo 6、修改当前spu的状态baseMapper.updateSpuStatus(spuId, ProductConstant.StatusEnum.SPU_UP.getCode());} else {//远程调用失败//todo 7.重复调用,接口幂等性。重试机制}} catch (Exception e) {log.error("es保存失败");}

6)productStatusUp编写

@Slf4j
@RequestMapping("/search/save")
@RestController
public class ElasticSaveController {@Autowiredprivate ProductSaveService productSaveService;/*** 商品上架* @param skuEsModels* @return*/@PostMapping("/product")public R productStatusUp(@RequestBody List<SkuEsModel> skuEsModels){Boolean b = false;try {b = productSaveService.productStatusUp(skuEsModels);} catch (IOException e) {log.error("ElasticSaveController商品上架错误;{}",e);return R.error(BizCodeEnume.PRODUCT_UP_EXCEPTION.getCode(),BizCodeEnume.PRODUCT_UP_EXCEPTION.getMsg());}if(b){return R.ok();}else {return R.error(BizCodeEnume.PRODUCT_UP_EXCEPTION.getCode(),BizCodeEnume.PRODUCT_UP_EXCEPTION.getMsg());}}
}

二:json数据转化

将json转化为需要的对象类型

1.构造typeReference 对象

TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};

泛型里面为需要转化为得对象类型

2.获取对象,进行转化

        Object data = get("data");String s = JSON.toJSONString(data);T t = JSON.parseObject(s,typeReference);

【大型电商项目开发】商品上架-es应用到商品上架-35相关推荐

  1. 【大型电商项目开发】商品服务之SPU检索SKU检索-29

    一:spu检索 请求url:/product/spuinfo/list 1.编辑list接口 1)编辑SpuInfoController的list方法 /*** 列表*/@RequestMapping ...

  2. 微信小程序电商项目开发实战漫谈

    原创文章,若转载请于明显处标明出处和相关链接:https://www.toutiao.com/i6567868839856439822/,否则追究其法律责任! 2018年小程序内容电商风口已成,如果我 ...

  3. 大型电商项目3.0实战+支付宝、微信支付项目实战

    须知:视频来源网络,侵权请联系删除! 大型电商项目3.0实战 获取方式 扫描下面二维码回复:A110 支付宝.微信支付项目实战 获取方式 扫描下面二维码回复:A106

  4. SpringCloud电商项目开发完整流程

    SpringCloud项目开发完整流程 一.新建前端Vue项目(管理后台) 先下载node.js Node官网 然后win+r,输入cmd打开命令行窗口,输入命令node -v,检测node是否安装成 ...

  5. 移动端电商项目开发流程

    目录 项目介绍 项目页面介绍 项目开发流程 首页介绍: 搜索页: 搜索页: 项目打包优化上线: 这是我自己写的一个电商开发流程,欢迎大家来补充! 项目介绍 我的项目叫✖✖✖✖,是B2C模式,也就是商家 ...

  6. 电商项目开发(系统功能分析、架构分析)

    文章目录 电商行业特点 常见的三种电商模式 系统功能分析 项目开发人员分配 技术选型与开发环境 技术 开发环境 架构分析 集中式 分布式 电商行业特点 技术范围广 分布式(一件事,拆开来做,例如,定个 ...

  7. 课堂笔记 - 电商项目开发笔记-02

    易购商城 第二天 目  录 1 课程计划 3 1.1 目标 3 1.2 功能分析 3 1.2.1 相关数据表 3 1.2.2 实现的思路 3 2 第一部分:实现商品类目选择功能 4 2.1 需求分析 ...

  8. 112.Spark大型电商项目-广告点击流量实时统计-需求分析、技术方案设计以及数据设计

    目录 需求分析 技术方案设计 数据表设计 ad_user_click_count //用户点击广告表 ad_blacklist //用户黑名单 ad_stat  //广告状态表 ad_province ...

  9. 1. Python_Django项目之大型电商项目介绍

    1.开发项目目的 联系已掌握的知识点 发现新的知识点 掌握开发技巧 掌握项目结构 增加项目经验 2.所用技术 语言:Python3(Django4) 数据库:MySQL web服务器:Nginx+uw ...

最新文章

  1. 配置管理小报111106:在wincvs中查找文件
  2. mac环境下myeclipse上配置tomcat
  3. Java学习笔记(三)--Java主类结构
  4. petshop4.0 详解之三(PetShop数据访问层之消息处理) [转]
  5. futureTask的超时原理解析
  6. Android App界面和流畅度优化
  7. 20 个免费的 jQuery 的工具提示插件:
  8. 点石成金 访客至上的Web和移动可用性设计秘笈pdf
  9. 基于Java的贪吃蛇游戏设计(含免费可用源代码)
  10. 华为HCIP(HCNP) RS路由交换认证考试学习心得体会(含考试内容和所占比例、ensp模拟器、221、222、223练习题下载)
  11. 对于三极管饱和状态的理解
  12. oracle获取字符串长度函数length()和hengthb()
  13. Taro Next 发布预览版:同时支持 React / Vue / Nerv
  14. elemen-ui表格默认样式的修改
  15. 基于Matlab的火灾预警系统
  16. f2fs学习笔记 -11. f2fs gc
  17. 关于java.util.concurrent.RejectedExecutionException: event executor terminated
  18. 学习无人机-C01小四轴无人机初体验
  19. 关于汇编跳转指令的说明
  20. JavaScript WebGL 使用图片疑惑点

热门文章

  1. 适合婚礼唱的流行歌_流行的婚礼歌曲被重新想象成数据即纸杯蛋糕
  2. mysql将查询结果作为临时表查询_mysql使用查询结果作为临时表
  3. swift 3.0 再探索 - 1.String
  4. 程序员的十层楼(http://softwareblogs-zho.intel.com/2009/02/04/1071/)
  5. Java实验报告(四)
  6. jquery Callbacks 回调对象的读书笔记-源码分析
  7. 你觉得java与嵌入式学哪个好?
  8. 任意地址读写驱动提权(cred、VDSO、modprobe_path、core_pattern、修改内核指针提权)
  9. DOS中SET命令的详细用法
  10. springBoot之springBoot简介