电商项目——商城业务-商品上架——第二章——中篇

本文详细介绍了电商项目中商品上架的流程,重点讨论了SKU在Elasticsearch(ES)中的存储模型,分析了nested数据类型在场景中的应用,并探讨了如何构造基本数据和SKU检索属性。同时,文章还涵盖了远程查询库存、泛型接口封装、远程上架接口的实现以及接口调试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

电商项目——全文检索-ElasticSearch——第一章——中篇
电商项目——商城业务-商品上架——第二章——中篇
电商项目——商城业务-首页——第三章——中篇
电商项目——性能压测——第四章——中篇
电商项目——缓存——第五章——中篇
电商项目——商城业务-检索服务——第六章——中篇
电商项目——商城业务-异步——第七章——中篇
电商项目——商品详情——第八章——中篇
电商项目——认证服务——第九章——中篇
电商项目——购物车——第十章——中篇
电商项目——消息队列——第十一章——中篇
电商项目——订单服务——第十二章——中篇
电商项目——分布式事务——第十三章——中篇

1:sku在es中的存储模型分析

es作为全文检索引擎,1.它承担项目里的所有全文检索功能,2.也会承担日志里面的全文检索信息功能(项目里面有些日志我们要进行快速定位,日志也有检索需求,我们把它传输到ES里面(有一个技术栈叫ELK,,LogStash负责收集日志,把收集来的日志存到ES里面,使用Kibana来进行可视化界面获取))
mysql的全文检索功能没有es强大,做这么复杂的检索数据,mysql性能不行(es都是将数据存在内存中)
在这里插入图片描述
在这里插入图片描述
第一步:将商品数据给es中存一份,去es里面检索商品数据,我们首先要分析,将那些数据保存在es中,在分析这个之前,我们要达成一个共识:es里面的数据都是存在内存中的,内存比硬盘贵的多,所以我们在es中只保存有用的数据,没用的信息不保存,要用的时候,大不了就直接检索出他们的id,然后再去数据库里面查找对应的信息,除了保存sku的信息,还要保存它的品牌,所属三级分类,还有他的规格检索
启动idea,webstorm,nacos
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如上会出现一个极大问题,检索手机的时候每选中一个规格,规格都在不断发生变化,最大的特点,查出的商品必须会展现出来,不可呢列出一个比如机身存储,它检索完没有
在这里插入图片描述
怎么动态计算出来的呢?
比如我们检索一个手机,他会找到标题里面所有包含手机的商品聚合起来,分析出这些商品里所有的规格参数(属性)和属性值,保证点击一个属性值,就会有对应的商品被检索出来

在这里插入图片描述
空间和时间不可以兼得,第一种方法浪费了空间获得了时间
第二种相反
最终我们商品中的es数据模型构建成如下的样子
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2:nested数据类型场景

嵌套类型是对象数据类型的专门化版本,它允许以一种可以相互独立查询的方式对对象数组进行索引。
在这里插入图片描述
https://www.elastic.co/guide/en/elasticsearch/reference/7.9/nested.html

  • 如果需要为对象数组建立索引并维护数组中每个对象的独立性,请使用嵌套数据类型而不是对象数据类型。
  • 在内部,嵌套对象索引数组中的每个对象作为一个单独的隐藏文档,这意味着每个嵌套对象可以通过嵌套查询独立于其他对象进行查询:
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "user": {
      //用户字段被映射为类型嵌套,而不是类型对象。
        "type": "nested" 
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
//这个查询不匹配,因为Alice和Smith不在同一个嵌套对象中。

GET my-index-000001/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "Smith" }} 
          ]
        }
      }
    }
  }
}

//这个查询匹配是因为Alice和White在同一个嵌套对象中。
GET my-index-000001/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "White" }} 
          ]
        }
      },
      "inner_hits": { 
        "highlight": {
          "fields": {
            "user.first": {}
          }
        }
      }
    }
  }
}

3:构造基本数据

在这里插入图片描述

响应数据
{
	"msg": "success",
	"code": 0
}

mall-product
SpuInfoController

@RestController
@RequestMapping("product/spuinfo")
public class SpuInfoController {
   
   
    @Autowired
    private SpuInfoService spuInfoService;

    // /product/spuinfo/{spuId}/up
    @PostMapping("/{spuId}/up")
    public R spuUp(@PathVariable("spuId") Long spuId){
   
   

        spuInfoService.spuUp(spuId);

        return R.ok();
    }

在这里插入图片描述
SpuInfoServiceImpl

 /**
     * 商品上架功能
     * @param spuId
     */
    @Override
    public void spuUp(Long spuId) {
   
   

//        List<SkuEsModel> uoProducts=new ArrayList<>();
        //1.组装需要的数据
//        SkuEsModel skuEsModel=new SkuEsModel();
        //1:查出当前spuid对应的所有sku信息,品牌名字
        List<SkuInfoEntity> skuInfoEntities= skuInfoService.getSkusBySpuId(spuId);

        //todo 4:查询出当前sku的所有的可以被用来检索的规格属性(只要查一遍就可以了,放在stream外面来做
//            private List<Attrs> attrs;
//            @Data
//            public static class  Attrs{
   
   
//                private Long attrId;
//                private String attrName;
//                private StringBuilder attrValue;
////            }
        //2:封装每个sku的信息
        List<SkuEsModel> collect = skuInfoEntities.stream().map((sku) -> {
   
   
            //1.组装需要的数据
            SkuEsModel skuEsModel = new SkuEsModel();
            //属性对拷
            BeanUtils.copyProperties(sku,skuEsModel);
            //SkuEsModel   SkuInfoEntity里面不一样的属性是:
            /**
             *     private BigDecimal skuPrice;
             private String skuImg;
             private Boolean hasStock;
             private Long hotScore;
             *   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 StringBuilder attrValue;
             }
             */
//            private BigDecimal skuPrice;
//            private String skuImg;
            skuEsModel.setSkuPrice(sku.getPrice());
            skuEsModel.setSkuImg(sku.getSkuDefaultImg());

//            private Boolean hasStock;
//            private Long hotScore;
            //todo 1:发送远程调用,库存系统查询是否有库存

            //todo 2:热度评分 0

            // todo 3:查询品牌和分类的名字信息
//            private String brandName;
//            private String brandImg;
            BrandEntity byId = brandService.getById(skuEsModel.getBrandId());
            skuEsModel.setBrandName(byId.getName());
            skuEsModel.setBrandImg(byId.getLogo());
//            private  String catalogName;
            CategoryEntity byId1 = categoryService.getById(skuEsModel.getCatalogId());
            skuEsModel.setCatalogName(byId1.getName());


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

        // todo:5:将数据发送给es进行保存:mall-search
    }

4:构造sku检索属性

在这里插入图片描述
AttrServiceImpl

    /**
     * 在指定的所有数据集合里面,挑选出检索属性
     * @param attrIds
     * @return
     */
    @Override
    public List<Long> selectSearchAttrs(List<Long> attrIds) {
   
   

        List<Long> longs = baseMapper.selectSearchAttrIds(attrIds);

        return longs;
    }

AttrDao

    <select id="selectSearchAttrIds" resultType="java.lang.Long">

        SELECT attr_id FROM 'pms_attr' WHERE attr_id IN
        <foreach collection="attrIds" item="id" separator="," open="(" close=")">
            #{attrIds}
        </foreach>
        and search_type=1
    </select>

SpuInfoServiceImpl

 /**
     * 商品上架功能
     * @param spuId
     */
    @Override
    public void spuUp(Long spuId) {
   
   

//        List<SkuEsModel> uoProducts=new ArrayList<>();
        //1.组装需要的数据
//        SkuEsModel skuEsModel=new SkuEsModel();
        //1:查出当前spuid对应的所有sku信息,品牌名字
        List<SkuInfoEntity> skuInfoEntities= skuInfoService.getSkusBySpuId(spuId);

        //todo 4:查询出当前sku的所有的可以被用来检索的规格属性(只要查一遍就可以了,放在stream外面来做
//            private List<Attrs> attrs;
//            @Data
//            public static class  Attrs{
   
   
//                private Long attrId;
//                private String attrName;
//                private StringBuilder attrValue;
////            }
//todo 4.1 检索出pms_product_attr_value中的AttrId的值通过spuId,然后在attrService中调用selectSearchAttrs过滤出search_type=0
        List<ProductAttrValueEntity> baseAttrs = productAttrValueService.baseAttrlistforspu(spuId);
        List<Long> attrIds = baseAttrs.stream().map((attr) -> {
   
   

            return attr.getAttrId();
        }).collect(Collectors.toList());

        List<Long> searchAttrId= attrService.selectSearchAttrs(attrIds);

        // todo 4.2 在baseAttrs中判断是否baseAttrs中的所有属性可以被上架,如果和searchAttrId相等就可以上架,并且保存在es中
        java.util.List<SkuEsModel.Attrs> attr=new ArrayList<>();
        HashSet<Long> idSet = new HashSet<>(searchAttrId);

        List
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值