day06 集成ES完成商品上架功能

1.名次介绍

  • index 索引:相当于mysql的database
  • type 类型: 相当于mysql的table
  • document 文档: 在某个index中的type里面的一条数据,是json格式的

2.初步检索

1._cat

  • postman测试 http://ip:9200/_cat/**

image-20220917201443830

2.ES数据扁平化处理

image-20220918195856846

  • ES添加一个数据 user是一个数组 但添加后es会做一个扁平化处理 处理后的数据是这个样子的

image-20220918200000947

  • 这个时候去检索就会有问题

    image-20220918200023275

  • 将user type设置嵌入式属性即可

    image-20220918200313289

3.boot整合es 7.12.1

1.导入pom

       <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>${elasticsearch-rest-high-level.version}</version>
        </dependency>
  • 但发现es client的版本并不是7.12.1而是boot设置的6.4

    image-20220918231058941

  • 解决 将pom版本改成7.12.1

    image-20220918231314365

4.完成商品上架功能

  • 功能实现:点击上传后需要将sku数据导入到es中

    image-20220923221000474

  • 安装es、ik、kibana

    docker run -d --name elasticsearch \
    -v /mydata/es/data:/usr/share/elasticsearch/data \
    --restart=always -p 9200:9200 -p 9300:9300 \
    -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
    -e "discovery.type=single-node" d9c406333741
    
    # 上传ik
    docker cp /mydata/es/plugins/ik elasticsearch:/usr/share/elasticsearch/plugins
    
    docker run -d \
    --name kibana \
    -e ELASTICSEARCH_HOSTS=http://10.211.55.3:9200 \
    -p 5601:5601  bae9450c8714
    
  • 1.引入es依赖

         <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-high-level-client</artifactId>
                <version>7.13.1</version>
         </dependency>
         
         # 因为我的springboot版本是2.1.8 所以es版本默认6.8 这里需要改成7.13.1
          <elasticsearch.version>7.13.1</elasticsearch.version>
    
  • 2.配置es连接信息

    @Configuration
    public class EsClientConfig {
    
        @Bean
        public RestHighLevelClient RestHighLevelClient() {
    
            RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost("10.211.55.3", 9200, "http")
                    ));
            return client;
        }
    }
    
  • controller层

        @PostMapping(value = "/{spuId}/up")
        public R spuUp(@PathVariable("spuId") Long spuId) {
            spuInfoService.up(spuId);
            return R.ok();
        }
    
  • sevice层

     @Override
        public void up(Long spuId) {
            //1、查出当前spuId对应的所有sku信息,品牌的名字
            List<SkuInfo> skuInfoEntities = skuInfoService.list(Wrappers.<SkuInfo>lambdaQuery().eq(SkuInfo::getSpuId,spuId));
    
            // 4、查出当前sku的所有可以被用来检索的规格属性
            List<ProductAttrValue> baseAttrs = productAttrValueService.baseAttrListForSpu(spuId);
            List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().map(item->{
                SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
                BeanUtil.copyProperties(item,attrs);
                return attrs;
            }).collect(Collectors.toList());
    
            // 获取skuId
            List<Long> skuIdList = skuInfoEntities.stream().map(SkuInfo::getSkuId).collect(Collectors.toList());
            // 1、发送远程调用,库存系统查询是否有库存
            Map<Long, Boolean> stockMap = new HashMap<>();
            try {
                R skuHasStock = wareFeignService.hasStock(skuIdList);
                TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};
                stockMap = skuHasStock.getData(typeReference).stream()
                        .collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
            } catch (Exception e) {
                log.error("库存服务查询异常:原因{}",e);
            }
    
            //2、封装每个sku的信息
            Map<Long, Boolean> finalStockMap = stockMap;
            List<SkuEsModel> collect = skuInfoEntities.stream().map(sku -> {
                //组装需要的数据
                SkuEsModel esModel = new SkuEsModel();
                esModel.setSkuPrice(sku.getPrice());
                esModel.setSkuImg(sku.getSkuDefaultImg());
    
                //设置库存信息
                if (finalStockMap == null) {
                    esModel.setHasStock(true);
                } else {
                    esModel.setHasStock(finalStockMap.get(sku.getSkuId()));
                }
    
                // 2、热度评分。0
                esModel.setHotScore(0L);
    
                //3、查询品牌和分类的名字信息
                Brand brandEntity = brandService.getById(sku.getBrandId());
                esModel.setBrandName(brandEntity.getName());
                esModel.setBrandId(brandEntity.getBrandId());
                esModel.setBrandImg(brandEntity.getLogo());
    
                Category categoryEntity = categoryService.getById(sku.getCatalogId());
                esModel.setCatalogId(categoryEntity.getCatId());
                esModel.setCatalogName(categoryEntity.getName());
    
                //设置检索属性
                esModel.setAttrs(attrsList);
    
                BeanUtils.copyProperties(sku,esModel);
    
                return esModel;
            }).collect(Collectors.toList());
    
            // 5、将数据发给es进行保存:gulimall-search
            R r = searchFeignService.productStatusUp(collect);
    
            if (r.getCode() == 0) {
                //远程调用成功
                // 6、修改当前spu的状态
                this.update(Wrappers.<SpuInfo>lambdaUpdate().eq(SpuInfo::getId,spuId)
                        .set(SpuInfo::getPublishStatus,ProductConstant.ProductStatusEnum.SPU_UP.getCode()));
            } else {
                //远程调用失败
                //TODO 7、重复调用?接口幂等性:重试机制
            }
        }
    
    
    
  • 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;
    
        }
    }
    
    # es mapping
    PUT product
    {
      "mappings": {
        "properties": {
          "skuId": {
            "type": "long"
          },
          "spuId": {
            "type": "long"
          },
          "skuTitle": {
            "type": "text",
            "analyzer": "ik_smart"
          },
          "skuPrice": {
            "type": "keyword"
          },
          "skuImg": {
            "type": "keyword",
            "index": false,
            "doc_values": false
          },
          "saleCount": {
            "type": "long"
          },
          "hosStock": {
            "type": "boolean"
          },
          "hotScore": {
            "type": "long"
          },
          "brandId": {
            "type": "long"
          },
          "catelogId": {
            "type": "long"
          },
          "brandName": {
            "type": "keyword",
            "index": false,
            "doc_values": false
          },
          "brandImg": {
            "type": "keyword",
            "index": false,
            "doc_values": false
          },
          "catelogName": {
            "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"
              }
            }
          }
        }
      }
    }
    
  • es导入代码实现

       @Override
        public boolean productStatusUp(List<SkuEsModel> skuEsModels) throws IOException {
            BulkRequest bulkRequest = new BulkRequest();
            for (SkuEsModel skuEsModel : skuEsModels) {
                bulkRequest.add(new IndexRequest(EsConstant.PRODUCT_INDEX).id(String.valueOf(skuEsModel.getSkuId()))
                        .source(JSONObject.toJSONString(skuEsModel), XContentType.JSON));
            }
            BulkResponse responses = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            // 是否有添加失败的 true=有
            boolean hasFailures = responses.hasFailures();
    
            List<String> ids = Arrays.stream(responses.getItems()).map(BulkItemResponse::getId).collect(Collectors.toList());
            log.info("商品上架完成:{}",ids);
            return hasFailures;
        }
    
  • 此处为什么要用这种方式来获取返回值?

    image-20220923221731592

    • 因为R继承了Map,如果使用泛型的话不会有返回值

    • 所以在查到结果后,调用R的setdata方法把值放到map中,取值的时候调用getdata传对应泛型就能拿到数据

      image-20220923221843498

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值