谷粒商城Es商品上架(1)

2023-10-15 09:31:16 浏览数 (2)

分析:商品上架在es中是存sku还是spu?

1)、检索的时候输入名字,是需要按照sku的title进行全文检索的 2)、检素使用商品规格,规格是spu的公共属性,每个spu是一样的 3)、按照分类id进去的都是直接列出spu的,还可以切换。 4〕、我们如果将sku的全量信息保存到es中(包括spu属性〕就太多字段了

代码语言:javascript复制
{
    skuId:1
    spuId:11
    skyTitile:华为mate
    price:999
    saleCount:99
    attr:[
        {尺寸:5},
        {CPU:高通945},
        {分辨率:全高清}
	]

缺点:如果每个sku都存储规格参数(如尺寸),会有冗余存储,因为每个spu对应的sku的规格参数都一样 

代码语言:javascript复制
sku索引
{
    spuId:1
    skuId:11
}
attr索引
{
    skuId:11
    attr:[
        {尺寸:5},
        {CPU:高通945},
        {分辨率:全高清}
	]
}

先找到4000个符合要求的spu,再根据4000个spu查询对应的属性,封装了4000个id,long 8B*4000=32000B=32KB 1K个人检索,就是32MB 结论:如果将规格参数单独建立索引,会出现检索时出现大量数据传输的问题,会引起网络网络 

最终采用第一种 

代码语言:javascript复制
PUT product
{
    "mappings":{
        "properties": {
            "skuId":{ "type": "long" },
            "spuId":{ "type": "keyword" },  # 不可分词
            "skuTitle": {
                "type": "text",
                "analyzer": "ik_smart"  # 中文分词器
            },
            "skuPrice": { "type": "keyword" },  # 保证精度问题
            "skuImg"  : { "type": "keyword" },  # 视频中有false
            "saleCount":{ "type":"long" },
            "hasStock": { "type": "boolean" },
            "hotScore": { "type": "long"  },
            "brandId":  { "type": "long" },
            "catalogId": { "type": "long"  },
            "brandName": {"type": "keyword"}, # 视频中有false
            "brandImg":{
                "type": "keyword",
                "index": false,  # 不可被检索,不生成index,只用做页面使用
                "doc_values": false # 不可被聚合,默认为true
            },
            "catalogName": {"type": "keyword" }, # 视频里有false
            "attrs": {
                "type": "nested",
                "properties": {
                    "attrId": {"type": "long"  },
                    "attrName": {
                        "type": "keyword",
                        "index": false,
                        "doc_values": false
                    },
                    "attrValue": {"type": "keyword" }
                }
            }
        }
    }
}
商品上架 

POST /product/spuinfo/{spuId}/up

代码语言:javascript复制
@GetMapping("/skuId/{id}")
public R getSkuInfoBySkuId(@PathVariable("id") Long skuId){

    SpuInfoEntity entity = spuInfoService.getSpuInfoBySkuId(skuId);
    return R.ok().setData(entity);
}
上架实体类

由于SpuInfoEntity与索引的数据模型并不对应,所以我们要建立专门的vo进行数据传输

代码语言:javascript复制
package com.atguigu.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 bandId;

    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;
    }
}
库存量查询 
代码语言:javascript复制
@PostMapping("/hasStock")
public R getSkuHasStock(@RequestBody List<Long> SkuIds){
    List<SkuHasStockVo> vos = wareSkuService.getSkuHasStock(SkuIds);
    return R.ok().setData(vos);
}

然后用feign调用 

代码语言:javascript复制
@FeignClient("gulimall-ware")
public interface WareFeignService {
    /**
     * 1.R设计的时候可以加上泛型(用这个)
     * 2.直接返回我们想要的类型
     * 3.自己封装解析结果
     * @param skuIds
     * @return
     */
    @PostMapping("/hasstock")
    public  R<List<SkuHasStockVo>> getSkuHashStock(@RequestBody List<Long> skuIds);
}

封装Es信息(未保存版本)

代码语言:javascript复制
 @Override
    public void up(Long spuId) {
        List<SkuEsModel> upProducts=new ArrayList<>();

        //1.组装我们需要的数据
        SkuEsModel esModel = new SkuEsModel();
        //1.查出spuid对应的sku的信息,品牌信息
        List<SkuInfoEntity> skus=  skuInfoService.getSkusByspuId(spuId);
        List<Long> skuIdList = skus.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());

        //2.封装sku的信息

        List<SkuEsModel> collect = skus.stream().map(sku -> {
            SkuEsModel esModel1 = new SkuEsModel();
            BeanUtils.copyProperties(sku,esModel1);
            //skuPrice skuImg hasStock hoteScore
            esModel1.setSkuPrice(sku.getPrice());
            esModel1.setSkuImg(sku.getSkuDefaultImg());
            //todo 运程发送请求,库存系统查询是否有库存
            Map<Long,Boolean> stockMap=null;
            try {
                R<List<SkuHasStockVo>> skuHashStock = wareFeignService.getSkuHashStock(skuIdList);
                 stockMap = skuHashStock.getData().stream().
                        collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
            }catch (Exception e){
                log.error("库存服务查询异常:原因{}",e);
            }
            //设置库存信息
         if (stockMap==null){
             esModel1.setHasStock(true);
         }else {
             esModel1.setHasStock(stockMap.get(sku.getSkuId()));
         }

            //todo 热度评分  0
            esModel1.setHotScore(0L);
            //todo 查询品牌和分类的名字信息
            BrandEntity brandEntity = brandService.getById(esModel1.getBandId());
            esModel1.setBrandName(brandEntity.getName());
            esModel1.setBrandImg(brandEntity.getLogo());
            CategoryEntity categoryEntity = categoryService.getById(esModel1.getCatalogId());
            esModel1.setCatalogName(categoryEntity.getName());
            // todo 查询当前所有的sku的所有可以被检索规格属性
            List<ProductAttrValueEntity> baseAttrs = attrValueService.baseAttrlistforspu(spuId);
            List<Long> attrIds = baseAttrs.stream().map(attr -> {
                return attr.getAttrId();
            }).collect(Collectors.toList());
           List<Long>  searchAttrIds= attrService.selectSearchAttrIds(attrIds);
            Set<Long> idSet=new HashSet<>(searchAttrIds);

            List<SkuEsModel.Attrs> atts=new ArrayList<>();

            List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().filter(item -> {
                return idSet.contains(item.getAttrId());
            }).map(item -> {
                SkuEsModel.Attrs attrs1 = new SkuEsModel.Attrs();
                BeanUtils.copyProperties(item, attrs1);
                return attrs1;
            }).collect(Collectors.toList());
            //设置检索属性
            esModel1.setAttrs(attrsList);


            /**
             *     private  String bandName;
             *
             *     private  String brandImg;
             *
             *     private  String catalogName;
             *      Attrs
             *       @Data
             *     static  class  Attrs{
             *         private  Long attrId;
             *
             *         private  String attrName;
             *
             *         private  String attrValue;
             *     }
             */
            return esModel1;
        }).collect(Collectors.toList());
        //todo 5.将数据发送给es进行保存 gulimall-search

0 人点赞