【业务功能篇84】微服务SpringCloud-ElasticSearch-Kibanan-电商实例应用

news2024/9/29 15:32:20

一、商品上架功能

ElasticSearch实现商城系统中全文检索的流程。

image.png

1.商品ES模型

商品的映射关系

PUT product 
{
	"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"
					}
				}
			}
		}
	}
}

2.netsted数据类型

参考官网地址:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/nested.html

3.实现上架功能

3.1 创建ESModel

点击上架功能传递spuId到后台,我们需要根据SpuID查询对应的信息,然后封装到自定义的Model对象中,然后将该对象传递给mall-search服务,所以我们需要先定义这样一个Model对象

@Data
public class SkuESModel {
    private Long skuId;
    private Long spuId;
    private String subTitle;
    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;
    }

}

3.2 上架逻辑实现

controller层

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

    /**
     * app/product/spuinfo/6/up
     * 商品的上架功能
     * 传递过来一个spuID
     * 我们就需要根据SPUID查询出需要存储在ElasticSearch中的数据
     * 然后把数据存储到ELasticSearch中,并修改该SPU的状态为上架
     */
    @PostMapping("/{spuId}/up")
    public R spuUp(@PathVariable("spuId") Long spuId){
        spuInfoService.up(spuId);
        return R.ok();
    }
}

核心service层方法实现

调用了一些同moudle下的其他实现类方法忽略

/**
     * 实现商品上架--》商品相关数据存储到ElasticSearch中
     * 1.根据SpuID查询出相关的信息
     *   封装到对应的对象中
     * 2.将封装的数据存储到ElasticSearch中--》调用mall-search的远程接口
     * 3.更新SpuID对应的状态--》上架
     *
     * @param spuId
     */
    @Override
    public void up(Long spuId) {
        // 1.根据spuId查询相关的信息 封装到SkuESModel对象中
        List<SkuESModel> skuEs = new ArrayList<>();
        // 根据spuID找到对应的SKU信息
        List<SkuInfoEntity> skus = skuInfoService.getSkusBySpuId(spuId);

        // 对应的规格参数  根据spuId来查询规格参数信息
        List<SkuESModel.Attrs> attrsModel = getAttrsModel(spuId);
        // 需要根据所有的skuId获取对应的库存信息---》远程调用
        List<Long> skuIds = skus.stream().map(sku -> {
            return sku.getSkuId();
        }).collect(Collectors.toList());
        Map<Long, Boolean> skusHasStockMap = getSkusHasStock(skuIds);
        // 2.远程调用mall-search的服务,将SukESModel中的数据存储到ES中
        List<SkuESModel> skuESModels = skus.stream().map(item -> {
            SkuESModel model = new SkuESModel();
            // 先实现属性的复制
            BeanUtils.copyProperties(item,model);
            model.setSubTitle(item.getSkuTitle());
            model.setSkuPrice(item.getPrice());

            // hasStock 是否有库存 --》 库存系统查询  一次远程调用获取所有的skuId对应的库存信息
            if(skusHasStockMap == null){
                model.setHasStock(true);
            }else{
                model.setHasStock(skusHasStockMap.get(item.getSkuId()));
            }
            // hotScore 热度分 --> 默认给0即可
            model.setHotScore(0l);
            // 品牌和类型的名称
            BrandEntity brand = brandService.getById(item.getBrandId());
            CategoryEntity category = categoryService.getById(item.getCatalogId());
            model.setBrandName(brand.getName());
            model.setBrandImg(brand.getLogo());
            model.setCatalogName(category.getName());
            // 需要存储的规格数据
            model.setAttrs(attrsModel);

            return model;
        }).collect(Collectors.toList());
        // 将SkuESModel中的数据存储到ES中
        R r = searchFeginService.productStatusUp(skuESModels);
        // 3.更新SPUID对应的状态
        // 根据对应的状态更新商品的状态
        log.info("----->ES操作完成:{}" ,r.getCode());
        System.out.println("-------------->"+r.getCode());
        if(r.getCode() == 0){
            // 远程调用成功  更新商品的状态为 上架
            baseMapper.updateSpuStatusUp(spuId, ProductConstant.StatusEnum.SPU_UP.getCode());
        }else{
            // 远程调用失败
        }
    }

Feign远程调用了其他微服务module

在当前需要调用远程微服务的模块中创建接口,通过注解@FeignClient(“mall-search”)找到对应被调用的微服务,接着将被调用微服务的controller层的所需方法名,形参路径等都全部复制过来,就能完成远程调用

@FeignClient("mall-search")
public interface SearchFeginService {

    @PostMapping("/search/save/product")
    public R productStatusUp(@RequestBody List<SkuESModel> skuESModels);
}

被调用的微服务模块Controller层

/**
 *
 * 存储商城数据到ElasticSearch的服务
 */
@Slf4j
@RequestMapping("/search/save")
@RestController
public class ElasticSearchSaveController {

    @Autowired
    private ElasticSearchSaveService service;

    /**
     * 存储商品上架信息到ElasticSearch服务的接口
     * @return
     */
    @PostMapping("/product")
    public R productStatusUp(@RequestBody List<SkuESModel> skuESModels){
        Boolean b = false;
        try {
            b = service.productStatusUp(skuESModels);
        } catch (IOException e) {
           // e.printStackTrace();
            log.error("ElasticSearch商品上架错误:{}",e);
            return R.error(BizCodeEnume.PRODUCT_UP_EXCEPTION.getCode(), BizCodeEnume.PRODUCT_UP_EXCEPTION.getMsg());
        }
        if(b){
            return R.ok();
        }
        return R.error(BizCodeEnume.PRODUCT_UP_EXCEPTION.getCode(), BizCodeEnume.PRODUCT_UP_EXCEPTION.getMsg());
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/933417.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mall:redis项目源码解析

文章目录 一、mall开源项目1.1 来源1.2 项目转移1.3 项目克隆 二、Redis 非关系型数据库2.1 Redis简介2.2 分布式后端项目的使用流程2.3 分布式后端项目的使用场景2.4 常见的缓存问题 三、源码解析3.1 集成与配置3.1.1 导入依赖3.1.2 添加配置3.1.3 全局跨域配置 3.2 Redis测试…

DataFrame.set_index()方法--Pandas

1.函数功能 为DataFrame重新设置索引&#xff08;行标签&#xff09; 2. 函数语法 DataFrame.set_index(keys, *, dropTrue, appendFalse, inplaceFalse, verify_integrityFalse)3. 函数参数 参数含义keys作为行标签的列名&#xff0c;可以DataFrame中的是单个列或者多列组…

【实例分割】(一)Mask R-CNN详细介绍带python代码

目录 1.&#x1f340;&#x1f340;实例分割定义 2.&#x1f340;&#x1f340;Mask R-CNN 3.&#x1f340;&#x1f340;经典的实例分割算法 4.&#x1f340;&#x1f340;Mask R-CNN python代码 整理不易&#xff0c;欢迎一键三连&#xff01;&#xff01;&#xff01;…

【FreeRTOS】【应用篇】任务管理相关函数

文章目录 前言一、函数解析1. 任务挂起 vTaskSuspend()① 使用场景② 设计思路③ 代码 2. 任务恢复 vTaskResume()① 作用② 设计思路③ 代码 3. 挂起任务调度器 vTaskSuspendAll()① 作用② 代码 4. 恢复任务调度器 xTaskResumeAll()① 设计思路② 代码 5. 任务删除函数 vTask…

牡丹宣言:七种皮肤类型|教你如何区分和保姆级护肤大法

经常听到有人说&#xff0c;我的皮肤T区油&#xff0c;脸颊干&#xff0c;应该是混合型皮肤吧 正常的皮肤根据皮脂腺分泌油脂量的多少可分为&#xff1a;中性&#xff0c;干性&#xff0c;油性&#xff0c;混合性。 接下来小编就帮大家细化整理了七种不同的皮肤类型&#xff0c…

Nginx详解 第一部分:编译安装Nginx+Nginx模块

Part 1 一 、HTTP 和 Nginx1.1 套接字Socket1.2 URL1.2.1 定义1.2.1 URL和URN的区别1.2.3 URL组成 1.3 请求访问完整过程详解 二、I/O模型 处理高并发的时候用2.1 I/O模型简介2.2 多路复用I/O型2.3 异步I/O模型2.4 事件模型 select poll epoll 三、NGINX概述3.1 简介3.2 NGINX和…

【Java并发】聊聊对象内存布局和syn锁升级过程

对象存储解析&#xff1a;一个空Object对象到底占据多少内存&#xff1f; 对象内存布局 Mark Word占用8字节&#xff0c;类型指针占用8个字节&#xff0c;对象头占用16个字节。 好了&#xff0c;我们来看一下一个Object对占用多少空间&#xff0c; 因为java默认是开启压缩…

帆软只是一个BI厂商?答案是“No”!

大数据产业创新服务媒体 ——聚焦数据 改变商业 2023年&#xff0c;8月17-19日&#xff0c;帆软智数大会落子花城广州&#xff0c;邀请了1200海内外CIO和数字化专家&#xff0c;共同探讨数字化转型新机遇。 值得关注的是&#xff0c;这也是帆软首次以BI和零代码双赛道第一的身…

django开发流程

设计model django采用ORM映射&#xff0c;可以在代码中描述数据库的布局 只需要导入from django.db import models 并使类继承models.Model&#xff0c;models中的一个类对应数据库中的一个表&#xff0c;类的变量对应表字段。 创建数据库 $ python manage.py makemigration…

Ubuntu【系统环境下】【编译安装OpenCV】【C++调用系统opencv库】

Ubuntu【系统环境下】【编译安装OpenCV】【C调用系统opencv库】 前言&#xff1a; 本人需要用C写代码&#xff0c;调用OpenCV库&#xff0c;且要求OpenCV版本号大于4.1.0 由于使用的是18.04的版本&#xff0c;所以apt安装OpenCV的版本始终是3.2.0&#xff0c;非常拉胯&#…

python爬虫的js逆向入门到进阶教程文章分享汇总~持续更新

目录 一、内容介绍二 、专栏内容-持续更新1、JS逆向入门2、Js逆向进阶3、爬虫基础知识4、工具与安装5、漫星内容分享 三、星球使用四、b站up主视频推荐 一、内容介绍 二 、专栏内容-持续更新 1、JS逆向入门 2023-08-25》11.常见加密>xx音乐RSA加密 https://articles.zsxq.c…

电视乱收费致200元电视也无人买,广电总局出手了,用户拍手欢迎

各个互联网企业盯着电视用户&#xff0c;将用户当韭菜&#xff0c;收费太狠&#xff0c;导致国内市场的电视销量暴跌&#xff0c;消费者怨声载道&#xff0c;日前国家广播电视台联合其他部门开展专项整治&#xff0c;狠杀这类乱收费的乱象&#xff0c;或许将有望挽回用户。 近几…

报错处理:MySQL数据库连接超时

具体报错&#xff1a; ERROR 2002 (HY000): Cant connect to local MySQL server through socket /var/run/mysqld/mysqld.sock (2) 报错环境&#xff1a;该报错一般发生在Linux服务器上运行MySQL数据库时&#xff0c;尝试连接MySQL时出现连接超时的情况。 排错思路&#xff1a…

VIOOVI分享:什么是动作分析?动作分析的方法有哪些?

动作分析是由吉尔布雷斯夫妇始创的&#xff0c;是根据操作者实施的动作顺序观察动作&#xff0c;用特定的标记记录以手和眼睛为中心的人体各部位的动作内容&#xff0c;掌握实际情况&#xff0c;并将上述记录制成图表的一套分析方法&#xff0c;在此基础上判断动作质量&#xf…

Docker容器学习:Dockerfile制作Web应用系统nginx镜像

目录 编写Dockerfile 1.文件内容需求&#xff1a; 2.编写Dockerfile&#xff1a; 3.开始构建镜像 4.现在我们运行一个容器&#xff0c;查看我们的网页是否可访问 推送镜像到私有仓库 1.把要上传的镜像打上合适的标签 2.登录harbor仓库 3.上传镜像 编写Dockerfile 1.文…

[机缘参悟-102] :IT人 - 管理的本质?管理人与从事技术的本质区别?人性、冰山模型、需求层次模型

感悟&#xff1a; 管理的本质是&#xff1a;学习各种管理理论、方法、技能&#xff0c;克服自身的人性缺点、预防他人人性的恶点、利用他人的人性特点拿到结果&#xff0c;从而完成组织、管理者的上司、管理者自身、管理者下属的目标。管理中的问题&#xff0c;80%以上都人性问…

基于实例的学习方法

基于实例的学习方法 动机基本概念基于实例的学习基于实例的概念表示 1. 最近邻最近邻的例子理论结果最近邻&#xff08;1- NN&#xff09;:解释问题 K-近邻(KNN)KNN讨论1 &#xff1a;距离度量KNN 讨论2&#xff1a;属性KNN:属性归一化KNN:属性加权 KNN讨论3:连续取值目标函数K…

数据结构(Java实现)LinkedList与链表(上)

链表 逻辑结构 无头单向非循环链表&#xff1a;结构简单&#xff0c;一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构&#xff0c;如哈希桶、图的邻接表等等。 无头双向链表&#xff1a;在Java的集合框架库中LinkedList底层实现就是无头双向循环链表。 链表的…

Stylet框架

Stylet框架 编辑时间:2023/8/25 1.Stylet简介 Stylet是一个小巧但功能强大的MVVM框架&#xff0c;灵感来自Caliburn.Micro。其目的是进一步降低复杂性和魔力&#xff08;译者注&#xff1a;Caliburn.Micro有很多让人抓狂的约定&#xff0c;看起来像魔法&#xff0c;这对新手…