在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),XContentType.JSON);
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),XContentType.JSON);
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);
}

hmall | 引入ES实现高效搜索与同步双写的更多相关文章

  1. 生产环境高可用centos7 安装配置RocketMQ-双主双从-同步双写(2m-2s-sync)

    添加hosts信息[四台机器] vim /etc/hosts 192.168.119.130 rocketmq-nameserver1 192.168.119.130 rocketmq-master1 ...

  2. Github高效搜索方式

    Github高效搜索方式 文章目录 Github高效搜索方式 0.写在前面 1.常用的搜索功能 1.1 直接搜索 1.2 寻找指定用户|大小的仓库 1.3 搜索仓库 1.4 查找特定star范围的仓库 ...

  3. ElasticSearch核心知识总结(一)es的六种搜索方式和数据分析

    es的六种搜索方式 query string search GET /ecommerce/product/_search //查询所有数据 { "took": 4,//耗费几毫秒 ...

  4. FP6397S5 高效、高频同步DC-DC降压变频器IC

    FP6397是一种高效.高频同步DC-DC降压变频器.100%占空比功能提供了低退出操作,延长了便携式系统的电池寿命. 内部同步开关提高了效率,并消除了对外部肖特基二极管的需要.在停机模式下,输入电源 ...

  5. a,b,c为3个整型变量,在不引入第四个变量的前提下写一个算法实现 a=b b=c c=a?(异或解决值互换问题)

    package com.Summer_0424.cn; /** * @author Summer * a,b,c为3个整型变量,在不引入第四个变量的前提下写一个算法实现 a=b b=c c=a? */ ...

  6. a,b为2个整型变量,在不引入第三个变量的前提下写一个算法实现 a与b的值互换

    package com.Summer_0424.cn; /** * @author Summer * a,b为2个整型变量,在不引入第三个变量的前提下写一个算法实现 a与b的值互换? */ publi ...

  7. 新引入thinkphp报错“应用目录[./Application/]不可写,目录无法自动生成! 请手动生成项目目录~”

    新引入thinkphp报错“应用目录[./Application/]不可写,目录无法自动生成! 请手动生成项目目录~”, 其主要原因是文件夹的权限问题,手动将项目文件夹权限更改为可读可写就OK,具体操 ...

  8. 【PHP高效搜索专题(2)】sphinx&coreseek在PHP程序中的应用实例

    PHP可以通过三种途径来调用sphinx 通过Sphinx官方提供的API接口(接口有Python,Java,Php三种版本) 通过安装SphinxSE,然后创建一个中介sphinxSE类型的表,再通 ...

  9. 【PHP高效搜索专题(1)】sphinx&Coreseek的介绍与安装

    我们已经知道mysql中带有"%keyword%"条件的sql是不走索引的,而不走索引的sql在大数据量+大并发量的时候,不仅效率极慢还很有可能让数据库崩溃.那我们如何通过某些关键 ...

  10. github高效搜索使用总结

    swoole 普通搜索 in:name swoole 搜索仓库的名称,搜索仓库名称包含swoole关键字的所有项目 in:description swoole 搜索描述中包含swoole关键字的项目 ...

随机推荐

  1. AI实用技巧 | 5分钟将coze集成到微信群机器人

    细心的小伙伴已经注意到,国内的Coze平台已经开放了API,这一发现让他们感到兴奋不已.因此,他们迫切地想要掌握这一机会,将API应用到实际中,让Coze成为他们的得力助手.这样一来,他们就可以避免每 ...

  2. 云原生时代的"应用级"多云管理

    作者:张齐 当前云计算有多种形态公有云.私有云.边缘云.虚拟机等,如何高效管理多云是当前面临的问题,在云原生时代,又该如何利用云原生技术实现多云管理?本文将讲解通过 Rainbond实现"应 ...

  3. @synchronized(self) 加锁引起的Crash

    一.最近米家App进入前台的时候上报上来一个Crash {"app_name":"MiHome","timestamp":"201 ...

  4. 如何创建一个线程池,为什么不推荐使用Executors去创建呢?

    我们在学线程的时候了解了几种创建线程的方式,比如继承Thread类,实现Runnable接口.Callable接口等,那对于线程池的使用,也需要去创建它,在这里我们提供2种构造线程池的方法: 方法一: ...

  5. Mysql 5.7 及以上版本修改密码

    登录数据后.选择 mysql 数据库 use mysql; 修改密码 update user set authentication_string=PASSWORD("mynewpasswor ...

  6. map数据类型

      MAP数据类型是一个类似于对象的数据类型             大型项目中会经常使用                      通过 构造函数来定义MAP数据类型             con ...

  7. kettle从入门到精通 第五十三课 ETL之kettle MQTT/RabbitMQ producer 实战

    1.MQTT介绍 MQTT (Message Queuing Telemetry Transport) 是一种轻量级的消息传输协议,设计用于连接低带宽.高延迟或不可靠网络的设备. MQTT 是基于发布 ...

  8. kettle从入门到精通 第五十一课 ETL之kettle Avro input

    1.我们在学习nifi的过程中有接触到Avro schema,当时我在想kettle应该也支持Avro,果不其然kettle也是支持Avro文件的读和写的.今天我们一起来学习下kettle中如何使用A ...

  9. Kubernetes监控手册06-监控APIServer

    写在前面 如果是用的公有云托管的 Kubernetes 集群,控制面的组件都交由云厂商托管的,那作为客户的我们就省事了,基本不用操心 APIServer 的运维.个人也推荐使用云厂商这个服务,毕竟 K ...

  10. mongodb基于角色的访问控制

    https://www.mongodb.com/docs/v4.4/tutorial/enable-authentication/ https://www.mongodb.com/docs/manua ...