首页 > 其他分享 >hmall | 引入ES实现高效搜索与同步双写

hmall | 引入ES实现高效搜索与同步双写

时间:2024-05-11 21:30:40浏览次数:21  
标签:status hmall request item es query id ES 双写

在gitee、飞书、百度云、B站中,黑马都没有上传该部分资料,以下皆为个人观点,如有纰漏欢迎指正

 

1.先把item-service中的searchcontroller抽出来,抽到一个模块中并将其设为hmall的子模块

2.引入依赖common,nacos,bootstrap,es

        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--common-->
        <dependency>
            <groupId>com.heima</groupId>
            <artifactId>hm-common</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!--nacos 服务注册发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--nacos配置管理-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!--读取bootstrap文件-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <!--es -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
        </dependency>

3.修改配置文件,bootstrap只改服务名,不需要的云配置不要写;application中添加上配置,实现自动装填

spring:
  elasticsearch:
    uris: http://192.168.88.95:9200

4.这时启动一下服务,看看nacos里有米有注册服务

5.我把文件直接CV过来了,因为这些东西应该不太公共,只是搜索相关会用到,因此没有抽取到common中

这里新增了一个ItemVO,其中字段就是为了对标输出内容中的total,pages,list三个数据,以便于传给前端

6.简单的实现了一下service层中的查询(可能没写全,不过差不多了)

@Service
@Slf4j
@RequiredArgsConstructor
public class ItemServiceImpl implements ItemService {
    private final RestHighLevelClient client;

    /*
     * total:"88475"
     * pages:"4424"
     * list[{},{},{}]
     * */
    public ItemVO search(ItemPageQuery query) throws IOException {
        Integer pageNo = Integer.valueOf(query.getPageNo());
        Integer pageSize = Integer.valueOf(query.getPageSize());
        SearchRequest request = new SearchRequest("hmall");
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if (query.getKey() != null && !query.getKey().isEmpty()) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("name", query.getKey()));
        }else {
            boolQueryBuilder.must(QueryBuilders.matchAllQuery());
        }

        if(query.getCategory()!=null){
            boolQueryBuilder.filter(QueryBuilders.termQuery("category", query.getCategory()));
        }
        if(query.getBrand()!=null){
            boolQueryBuilder.filter(QueryBuilders.termQuery("brand", query.getBrand()));
        }

        if(query.getSortBy()!=null&&query.getIsAsc().equals("false")){
            request.source().sort(query.getSortBy(), SortOrder.DESC);
        }else if(query.getSortBy()!=null&&query.getIsAsc().equals("true")){
            request.source().sort(query.getSortBy(), SortOrder.ASC);
        }
        if(query.getMinPrice()!=null&&query.getMaxPrice()!=null){
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(query.getMinPrice()).lte(query.getMaxPrice()));
        }

        // 分页
        request.source().query(boolQueryBuilder).from((pageNo - 1) * pageSize).size(pageSize);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hit = response.getHits();

        SearchHit[] hits = hit.getHits();
        List<ItemDoc>list=new ArrayList<>();
        for (SearchHit documentFields : hits) {
            String sourceAsString = documentFields.getSourceAsString();
            ItemDoc itemDoc= JSONUtil.toBean(sourceAsString,ItemDoc.class);
            list.add(itemDoc);
        }
        long total=hit.getTotalHits().value;
        return ItemVO.builder()
                .total(total)
                .list(list)
                .pages(total/(list.size()+1))
                .build();
    }
}

7.为了保持mysql与es的同步,我选择了最简单的同步双写

在item-service的controller中修改controller方案,当商品上架的时候(status==1),我们把mysql的这条数据写到es中,当商品下架的时候(status==2),我们把es中的数据删除掉。因为es存储没有涉及到库存问题,因此我只是简单的改了改controller层,发生了代码侵入

    @ApiOperation("新增商品,如果status是1就写入es")
    @PostMapping
    public void saveItem(@RequestBody ItemDTO item) throws IOException {
        // 新增
        itemService.save(BeanUtils.copyBean(item, Item.class));
        if(item.getStatus()==1){
            IndexRequest request=new IndexRequest("hmall");
            ItemDoc itemDoc = BeanUtils.copyBean(itemService.getById(item.getId()), ItemDoc.class);
            request.source(JSONUtil.toJsonStr(itemDoc));
            client.index(request, RequestOptions.DEFAULT);
        }
    }

    @ApiOperation("更新商品状态,如果是上架,就添加到es中,下架就在es中删除")
    @PutMapping("/status/{id}/{status}")
    public void updateItemStatus(@PathVariable("id") Long id, @PathVariable("status") Integer status) throws IOException {
        Item item = new Item();
        item.setId(id);
        item.setStatus(status);
        itemService.updateById(item);
        //1 正常 需上传
        if(status==1){
            IndexRequest request=new IndexRequest("hmall");
            ItemDoc itemDoc = BeanUtils.copyBean(itemService.getById(id), ItemDoc.class);
            request.source(JSONUtil.toJsonStr(itemDoc));
            client.index(request, RequestOptions.DEFAULT);
        }
        //2 下架 需删除
        else if(status==2||status==3){
            DeleteRequest request=new DeleteRequest("hmall",id.toString());
            client.delete(request, RequestOptions.DEFAULT);
        }
    }

    @ApiOperation("根据id删除商品 同步双删")
    @DeleteMapping("{id}")
    public void deleteItemById(@PathVariable("id") Long id) throws IOException {
        itemService.removeById(id);
        // es中也要同步删除
        DeleteRequest request=new DeleteRequest("hmall",id.toString());
        client.delete(request, RequestOptions.DEFAULT);
    }

 

标签:status,hmall,request,item,es,query,id,ES,双写
From: https://www.cnblogs.com/kun1790051360/p/18187178

相关文章

  • [code notes] check_agg_arguments
    TheSQLselectsum(sum(a))frommyt1groupbya;Thisnotefocusesonlyonsum(sum(a))andit'sabouthowpostgresrejectsthesqlabove.Notessum(sum(a))|||||\_innermostargument,Varnode|\_ functioncall\_functioncal......
  • Codeforces Round 944 (Div. 4) 补题
    A.MyFirstSortingProblemYouaregiventwointegersxandy.Outputtwointegers:theminimumofxandy,followedbythemaximumofxandy.题意:给你两个整数求出最小值和最大值Code:#include<bits/stdc++.h> usingnamespacestd;#definedebug(x)cer......
  • AngleScript语法
     Class的使用要继承于Interface或者Mixin class.Mixinclass实际上就是类似于抽象类,它已经实现的,在子类里面不能实现,类似如下代码:interfaceAInterface{ voidDoSomething1(); voidDoSomething2();}//如果不用mixin那么必须实现该接口的所有函数mixinclassABa......
  • 七十八、fiddler、Charles请求重定向---路由转发Map Remote
    一、fiddlerfiddler、charles的MapRemote(请求重定向)功能,说白了就是你本来要请求A接口拿数据,重定向后,你实际请求的是B接口,拿到的是B接口返回的数据。     二、Charles......
  • C# 使用QuestPDF各种报错,System.IO.FileNotFoundException:“未能加载文件或程序集,Dll
    最近要做一个生成pdf报告的小功能,搜索一番之后,选择了QuestPDF这个库由于我是要在netframework4.8中实现功能,可能使用场景太老了,导致使用过程一波三折,非常的坎坷,折腾了一下午,增长了一些经验,记录下来1,如果你要在netframework4.8框架中使用,就不要自作聪明的用netstandard2.0框架......
  • Kubernetes Dashboard部署安装recommended.yaml
    ```yml#Copyright2017TheKubernetesAuthors.##LicensedundertheApacheLicense,Version2.0(the"License");#youmaynotusethisfileexceptincompliancewiththeLicense.#YoumayobtainacopyoftheLicenseat##http://www.apache.......
  • 网易Airtest集群方案大揭秘:小型便携式集群方案来啦
    此文章来源于项目官方公众号:“AirtestProject”版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途一、前言中小型企业/工作室搭建便携设备集群的制胜法宝是什么?当然非网易Airtest便携式机柜莫属啦。得益于广大企业客户对我们便携式集群的支持,我们团队也一直在坚......
  • Codeforces 832E Vasya and Shifts
    考虑到这个操作实际上就是\(5\)进制的不进位加法,其实也就是\(5\)进制下的异或。同时因为是\(5\)进制,对于\(x\in[1,4]\),\(x\times0,\cdots,x\times4\)刚好可以表示出\(0\sim4\)。于是可以考虑类似\(2\)进制的线性基弄个\(5\)进制的线性基。即令\(w_i\)为......
  • CF207C3 Game with Two Trees
    CF207C3GamewithTwoTrees妙到家的树上字符串问题。约定树\(1\):\(t_1\)。树\(2\):\(t_2\)。\(S_{1/2}(i,l)\)为树\(1/2\)上节点\(i\)沿父亲走经过\(l\)​条边所构成的字符串。\(E_{1/2}(u,v)\)为树\(1/2\)上,连接节点\(u,v\)​的边的字符。\(fa_{......
  • m基于FPGA的MPPT最大功率跟踪算法verilog实现,包含testbench
    1.算法仿真效果其中Vivado2019.2仿真结果如下:   使用matlab进行显示如下:   2.算法涉及理论知识概要       在太阳能光伏系统中,最大功率点跟踪(MaximumPowerPointTracking,MPPT)是提高能量转换效率的关键技术之一。爬山法(HillClimbingAlgorithm,HCA)......