首页 > 其他分享 >spring cloud整合ElasticSearch

spring cloud整合ElasticSearch

时间:2023-07-23 13:45:09浏览次数:38  
标签:false spuId spring List ElasticSearch type esModel public cloud

 

1. 创建一个查询服务,pom中引入es服务所需要的包

<dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.4.2</version>
        </dependency>

 

2. 创建配置类,在类中指定es服务连接信息

@Configuration
public class GulimallElasticSearchConfig {

    public static final RequestOptions COMMON_OPTIONS;
    static {
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
        // builder.addHeader("Authorization", "Bearer " + TOKEN);
        // builder.setHttpAsyncResponseConsumerFactory(
        //         new HttpAsyncResponseConsumerFactory
        //                 .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
        COMMON_OPTIONS = builder.build();
    }


     @Bean
     public RestHighLevelClient esRestClient(){
         RestHighLevelClient client = new RestHighLevelClient(
                 RestClient.builder(new HttpHost("123.xx.xx.xx", 9200, "http")));
         return  client;
     }
}

 

3.  在查询服务中,对外提供保存到es的接口,在保存之前先在使用kibana在es中建立product索引的映射关系

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"
          }
        }
      }
    }
  }
}

GET product/_search

  在controller类中接口实现类中,实现保存es的方法

@Slf4j
@RequestMapping(value = "/search/save")
@RestController
public class ElasticSaveController {

    @Autowired
    private ProductSaveService productSaveService;

    @PostMapping(value = "/product")
    public R productStatusUp(@RequestBody List<SkuEsModel> skuEsModels) {
        boolean status=false;
        try {
            status = productSaveService.productStatusUp(skuEsModels);
        } catch (IOException e) {

            return R.error(BizCodeEnume.PRODUCT_UP_EXCEPTION.getCode(),BizCodeEnume.PRODUCT_UP_EXCEPTION.getMsg());
        }

        if(status){
            return R.error(BizCodeEnume.PRODUCT_UP_EXCEPTION.getCode(),BizCodeEnume.PRODUCT_UP_EXCEPTION.getMsg());
        }else {
            return R.ok();
        }
    }
}
@Slf4j
@Service("productSaveService")
public class ProductSaveServiceImpl implements ProductSaveService {

    @Autowired
    private RestHighLevelClient esRestClient;


    @Override
    public boolean productStatusUp(List<SkuEsModel> skuEsModels) throws IOException {
        //1. 在es中建立索引,建立映射关系
        //2. 数据保存到es中
        BulkRequest bulkRequest = new BulkRequest();
        for (SkuEsModel model : skuEsModels){
            IndexRequest indexRequest = new IndexRequest(EsConstant.PRODUCT_INDEX);
            indexRequest.id(model.getSkuId().toString());
            String s = JSON.toJSONString(model);
            indexRequest.source(s, XContentType.JSON);

            bulkRequest.add(indexRequest);
        }
        BulkResponse bulk = esRestClient.bulk(bulkRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);
        //如果发生错误
        boolean b = bulk.hasFailures();
        List<String> list = Arrays.stream(bulk.getItems()).map(item -> item.getId()).collect(Collectors.toList());
        log.info("商品上架:{}",list);
        return b;
    }
}

 

4. 在业务服务中,提供feign接口,同时在业务controller中调用对外暴露的feign接口,实现调用接口来把数据保存到es中

@FeignClient("gulimall-search")
public interface SearchFeignService {

    @PostMapping(value = "/search/save/product")
    public R productStatusUp(@RequestBody List<SkuEsModel> skuEsModels);

}
    //商品上架
    ///product/spuinfo/{spuId}/up
    @PostMapping(value = "/{spuId}/up")
    public R spuUp(@PathVariable("spuId") Long spuId) {

        spuInfoService.up(spuId);

        return R.ok();
    }
@Override
    public void up(Long spuId) {
//1、查出当前spuId对应的所有sku信息,品牌的名字
        List<SkuInfoEntity> skuInfoEntities = skuInfoService.getSkusBySpuId(spuId);
        //TODO 4、查出当前sku的所有可以被用来检索的规格属性
        List<ProductAttrValueEntity> baseAttrs = attrValueService.baseAttrlistforspu(spuId);

        List<Long> attrIds = baseAttrs.stream().map(attr -> {
            return attr.getAttrId();
        }).collect(Collectors.toList());
        List<Long> searchAttrIds = attrService.selectSearchAttrs(attrIds);
        //转换为Set集合
        Set<Long> idSet = searchAttrIds.stream().collect(Collectors.toSet());
        List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().filter(item -> {
            return idSet.contains(item.getAttrId());
        }).map(item -> {
            SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
            BeanUtils.copyProperties(item, attrs);
            return attrs;
        }).collect(Collectors.toList());

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

        //TODO 1、发送远程调用,库存系统查询是否有库存
        Map<Long, Boolean> stockMap = null;

        try {
            R skuHasStock = wareFeignService.getSkuHasStock(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()));
            }

            //TODO 2、热度评分。0
            esModel.setHotScore(0L);

            //TODO 3、查询品牌和分类的名字信息
            BrandEntity brandEntity = brandService.getById(sku.getBrandId());
            esModel.setBrandName(brandEntity.getName());
            esModel.setBrandId(brandEntity.getBrandId());
            esModel.setBrandImg(brandEntity.getLogo());

            CategoryEntity 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());

        //TODO 5、将数据发给es进行保存:gulimall-search
        R r = searchFeignService.productStatusUp(collect);
        if (r.getCode() == 0) {
            //远程调用成功
            //TODO 6、修改当前spu的状态
            this.baseMapper.updaSpuStatus(spuId, ProductConstant.ProductStatusEnum.SPU_UP.getCode());
        } else {
            //远程调用失败
            //TODO 7、重复调用?接口幂等性:重试机制
        }
    }

 

  5. 当调用商品服务的上架方法后,会把商品保存到es中,在kibana中查询product索引,可以看到保存的商品数据

  GET product/_search

{
  "took" : 127,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "product",
        "_type" : "_doc",
        "_id" : "27",
        "_score" : 1.0,
        "_source" : {
          "attrs" : [
            {
              "attrId" : 15,
              "attrName" : "CPU品牌",
              "attrValue" : "高通(Qualcomm)"
            },
            {
              "attrId" : 16,
              "attrName" : "CPU型号",
              "attrValue" : "骁龙665"
            }
          ],
          "brandId" : 10,
          "brandImg" : "https://gulimall-hello.oss-cn-beijing.aliyuncs.com/2019-11-18/1f9e6968-cf92-462e-869a-4c2331a4113f_xiaomi.png",
          "brandName" : "小米",
          "catalogId" : 225,
          "catalogName" : "手机",
          "hasStock" : true,
          "hotScore" : 0,
          "saleCount" : 0,
          "skuId" : 27,
          "skuImg" : "https://lewang-yygh.oss-cn-hangzhou.aliyuncs.com/2023-07-23//5a07c9a9-d223-4ae5-873a-38b259ec7267_6a1b2703a9ed8737.jpg",
          "skuPrice" : 0.0,
          "skuTitle" : "xiaomi11 白色 6GB",
          "spuId" : 15
        }
      }
    ]
  }
}

 

标签:false,spuId,spring,List,ElasticSearch,type,esModel,public,cloud
From: https://www.cnblogs.com/homle/p/17574920.html

相关文章

  • Spring 事务管理
    事务事务是一组操作的集合,它是一个不可分割的单位,这些操作要么成功,要么失败。操作开启事务(一组操作开始前,开启事务):starttranasction/begin;提交事务(这组操作全部成功,提交事务):commit回滚事务(中间任何一个操作出现异常,回滚事务):rollback一、Spring事务管理当涉及多表......
  • SpringBoot 自动装载 Bean
    我们在工作中经常会遇到这样的场景,我们写了很多非常实用的工具类,这些类在多个项目工程中使用非常频繁。如果在每个要使用的项目工程中都去编写加载bean的代码的话,那么重复的代码就太多了。如果你想追求完美只写一份代码的话,使用SpringBoot的自动装载的特性是一个很不错的方案......
  • JVAA springboot 项目启动后,localhost加端口可以访问,但是外网IP不行// OCPP KYOHOON
     现象javaspringboot项目启动后,localhost(或127.0.0.1)加端口可以访问,但是使用外网IP却无法访问。   原因及解决方法springboot的配置文件(yml或properties)中缺少server.address的设置。解决方法:在springboot的配置文件中增加server.address的配置。yml配......
  • springboot整合activeMQ
    依赖<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4......
  • idea打包springboot项目,打包成war包,如何不把lib目录或指定jar打进去?
    1、在pom.xml文件中添加如下配置:<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration>......
  • springboot3.0 从入门到高级学习路线,技术精讲?
    springboot3.0从入门到高级学习路线,技术精讲?学习SpringBoot3.0的技术精讲需要经历以下几个阶段:阶段一:基础知识学习1.Java基础:熟悉Java编程语言及面向对象的基本概念和语法。2.Spring基础:了解Spring框架的核心概念和基本用法,包括依赖注入、AOP等。3.SpringBoot基础:学习Spr......
  • 如何理解Spring的IOC和DI
    学习过Spring框架的人一定都会听过Spring的IoC(控制反转)、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IOC、DI这两个概念是模糊不清的,是很难理解的。今天我就谈谈我对IOC和DI的理解,希望对大家有帮助。1、IOC与DI介绍IOC是InversionofControl的缩写,翻译成中文是......
  • RabbitMQ(三)整合SpringBoot
    RabbitMQ(三)整合SpringBoot1整合RabbitMQ1导入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>2查看容器的自动配置......
  • 10道SpringBoot面试题
    SpringBoot我是JavaPub,专注于面试、副业,技术人的成长记录。以下是SpringBoot面试题,相信大家都会有种及眼熟又陌生的感觉、看过可能在短暂的面试后又马上忘记了。JavaPub在这里整理这些容易忘记的重点知识及解答,建议收藏,经常温习查阅。评论区见本系列《最少必要面试题》Sprin......
  • 如何动态修改 spring aop 切面信息?让自动日志输出框架更好用
    业务背景很久以前开源了一款auto-log自动日志打印框架。其中对于spring项目,默认实现了基于aop切面的日志输出。但是发现一个问题,如果切面定义为全切范围过大,于是v0.2版本就是基于注解@AutoLog实现的。只有指定注解的类或者方法才会生效,但是这样使用起来很不方便。......