在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. Android 13 - Media框架(24)- OMXNodeInstance(一)

    关注公众号免费阅读全文,进入音视频开发技术分享群! 为了了解 ACodec 是如何与 OpenMAX 组件进行 buffer 流转的,我们有必要先来学习 OMXNodeInstance,在前面的章节中 ...

  2. C# WinForm控件及其子控件转成图片(支持带滚动条的长截图)

    概述(Overview) 参考了网上的分析,感觉都不太理想:1.一个控件内如果包含多个子控件时没有考虑顺序问题:2.超出控件可显示区域时不能长截图,有滚动条会多余截取了滚动条.这个随笔旨在解决这个问题 ...

  3. 使用C#开发微信公众号对接ChatGPT和DALL-E

    本人是一家小公司的技术总监,工作包括写市场分析.工作汇报.产品推广文案及代码开发等.在ChatGPT推出之后本人一直在工作中使用,在头脑风暴.大纲生成.语句优化.代码生成方面很有效果.但ChatGPT ...

  4. 如果设备不支持vulkan,就用swiftshader,否则就加载系统的vulkan的正确姿势(让程序能够智能的在vulkan-1.dll和libvk_swiftshader.dll之间切换)

    一些老的显卡设备没有更新驱动,甚至根本就不支持Vulkan的显卡,遇到静态链接的vulkan-1.lib文件,启动exe就会崩溃. 你以为从别的机器拷贝这个vulkan-1.dll就可以了吗? 太傻太 ...

  5. Python 潮流周刊#54:ChatTTS 强大的文本生成语音模型

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  6. 华为云短信服务教你用C++实现Smgp协议

    本文分享自华为云社区<华为云短信服务教你用C++实现Smgp协议>,作者:张俭. 引言&协议概述 中国联合网络通信有限公司短消息网关系统接口协议(SGIP)是中国网通为实现短信业务 ...

  7. new 和 delete 运算符

    C++ 支持使用操作符 new 和 delete 来动态分配和释放对象. new 运算符调用特殊函数 operator new,delete 运算符调用特殊函数 operator delete. 如果 ...

  8. c++引用(REFERENCES)

    一个例子 void add(int value) { value++; } int main() { int a = 5; LOG(a); add(a); LOG( a); } 在这种情况下,变量a在 ...

  9. Kotlin 变量详解:声明、赋值与最佳实践指南

    Kotlin 变量 变量是用于存储数据值的容器. 要创建一个变量,使用 var 或 val,然后使用等号(=)给它赋值: 语法 var 变量名 = 值 val 变量名 = 值 示例 var name ...

  10. metal invalid pixel format xx

    这个时候要考虑CAMetalLayer.pixelFormat是否设置设置正确,虽然MTLPixelFormat有很多枚举值,但是CAMetalLayer支持的也就只有五个: MTLPixelForm ...