hmall | 引入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),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实现高效搜索与同步双写的更多相关文章
- 生产环境高可用centos7 安装配置RocketMQ-双主双从-同步双写(2m-2s-sync)
添加hosts信息[四台机器] vim /etc/hosts 192.168.119.130 rocketmq-nameserver1 192.168.119.130 rocketmq-master1 ...
- Github高效搜索方式
Github高效搜索方式 文章目录 Github高效搜索方式 0.写在前面 1.常用的搜索功能 1.1 直接搜索 1.2 寻找指定用户|大小的仓库 1.3 搜索仓库 1.4 查找特定star范围的仓库 ...
- ElasticSearch核心知识总结(一)es的六种搜索方式和数据分析
es的六种搜索方式 query string search GET /ecommerce/product/_search //查询所有数据 { "took": 4,//耗费几毫秒 ...
- FP6397S5 高效、高频同步DC-DC降压变频器IC
FP6397是一种高效.高频同步DC-DC降压变频器.100%占空比功能提供了低退出操作,延长了便携式系统的电池寿命. 内部同步开关提高了效率,并消除了对外部肖特基二极管的需要.在停机模式下,输入电源 ...
- 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? */ ...
- a,b为2个整型变量,在不引入第三个变量的前提下写一个算法实现 a与b的值互换
package com.Summer_0424.cn; /** * @author Summer * a,b为2个整型变量,在不引入第三个变量的前提下写一个算法实现 a与b的值互换? */ publi ...
- 新引入thinkphp报错“应用目录[./Application/]不可写,目录无法自动生成! 请手动生成项目目录~”
新引入thinkphp报错“应用目录[./Application/]不可写,目录无法自动生成! 请手动生成项目目录~”, 其主要原因是文件夹的权限问题,手动将项目文件夹权限更改为可读可写就OK,具体操 ...
- 【PHP高效搜索专题(2)】sphinx&coreseek在PHP程序中的应用实例
PHP可以通过三种途径来调用sphinx 通过Sphinx官方提供的API接口(接口有Python,Java,Php三种版本) 通过安装SphinxSE,然后创建一个中介sphinxSE类型的表,再通 ...
- 【PHP高效搜索专题(1)】sphinx&Coreseek的介绍与安装
我们已经知道mysql中带有"%keyword%"条件的sql是不走索引的,而不走索引的sql在大数据量+大并发量的时候,不仅效率极慢还很有可能让数据库崩溃.那我们如何通过某些关键 ...
- github高效搜索使用总结
swoole 普通搜索 in:name swoole 搜索仓库的名称,搜索仓库名称包含swoole关键字的所有项目 in:description swoole 搜索描述中包含swoole关键字的项目 ...
随机推荐
- 算法金 | 10 大必知的自动化机器学习库(Python)
大侠幸会,在下全网同名[算法金] 0 基础转 AI 上岸,多个算法赛 Top [日更万日,让更多人享受智能乐趣] 一.入门级自动化机器学习库 1.1 Auto-Sklearn 简介: Auto-Skl ...
- kettle从入门到精通 第四十二课 kettle 1对多表拆分同步
1.在有的业务场景中,会涉及一对多表拆分同步的业务场景,也就是说原表是一张表,将原表字段进行拆分放入目标库中的多张表,如下面的示例将表student_third中的数据 同步到student.teac ...
- C# .NET MVC 表单提交前校验数据等
页面上写2个button,一个普通button,另一个是submit,submit的这个隐藏.校验函数写在普通button里,普通button click函数中去提交表单. 页面: <input ...
- VictoriaLogs 要凭什么革了各家日志存储的命
如果大家对时序指标的存储方案有些了解,那大概率会听过 VictoriaMetrics,VictoriaMetrics 号称 Prometheus 的升级版,在性能和成本方面也确实做得很好,如果是夜莺新 ...
- Scrapy框架(二)--持久化存储
持久化存储 scrapy的高性能持久化存储操作,有两种方式:基于终端指令的持久化存储 和 基于管道的持久化存储操作. 基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列 ...
- XML文档定义的几种形式和本质区别
XML文档定义的形式 两种定义形式:DTD.Schema DTD:数据类型定义(Data Type Definition),用以描述XML文档的文档结构,是早期的XML文档定义形式. Schema:其 ...
- Spring源码——详细流程图(超详细)
Spring源码流程图
- Thread的join方法demo
Thread的join方法demo /** * 关于join官方的解释是 Waits for this thread to die. 也就是等待一个线程结束. */ public class Thre ...
- c++引用(REFERENCES)
一个例子 void add(int value) { value++; } int main() { int a = 5; LOG(a); add(a); LOG( a); } 在这种情况下,变量a在 ...
- Nuxt 3 路由系统详解:配置与实践指南
title: Nuxt 3 路由系统详解:配置与实践指南 date: 2024/6/21 updated: 2024/6/21 author: cmdragon excerpt: 摘要:本文是一份关于 ...