Mongodb:业务应用(1)

环境搭建参考:mongodb:环境搭建_Success___的博客-CSDN博客

 需求:

        在文章搜索服务中实现保存搜索记录到mongdb

        并在搜索时查询出mongdb保存的数据

1、安装mongodb依赖

        <dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-mongodb</artifactId></dependency>

2、创建数据库对应实体类

package com.heima.model.common.search;import lombok.Data;
import org.springframework.data.mongodb.core.mapping.Document;import java.io.Serializable;
import java.util.Date;/*** <p>* APP用户搜索信息表* </p>* @author itheima*/
@Data
@Document("ap_user_search")
public class ApUserSearch implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/private String id;/*** 用户ID*/private Integer userId;/*** 搜索词*/private String keyword;/*** 创建时间*/private Date createdTime;}

3、配置nacos

spring:data:mongodb:host: 192.168.200.130port: 27017database: leadnews-history

实现保存

1、在搜索服务的service层新增搜索历史保存方法insert

package com.heima.search.service;import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.search.UserSearchDto;import java.io.IOException;public interface ArticleSearchService {/*文章搜索*/ResponseResult search(UserSearchDto dto) throws IOException;/*** 保存用户搜索历史记录* @param keyword* @param userId*/void insert(String keyword,Integer userId);}

2、实现类

package com.heima.search.service.impl;import com.heima.model.common.search.ApUserSearch;
import com.heima.search.service.ArticleSearchService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;import java.util.Date;
import java.util.List;@Service
@Slf4j
public class ArticleSearchServiceImpl implements ArticleSearchService {@AutowiredMongoTemplate mongoTemplate;/*** 保存用户搜索历史记录* @param keyword* @param userId*/@Override@Asyncpublic void insert(String keyword, Integer userId) {/*查询当前用户搜索的关键字*///构造查询条件Query query = Query.query(Criteria.where("userid").is(userId).and("keyword").is(keyword));//执行mongodb库的查询ApUserSearch userSearch = mongoTemplate.findOne(query, ApUserSearch.class);/*存在则更新创建时间重新保存*/if(userSearch != null) {userSearch.setCreatedTime(new Date());mongoTemplate.save(userSearch);return;}/*不存在,判断当前搜索记录数量是否超过10条*/userSearch = new ApUserSearch();userSearch.setUserId(userId);userSearch.setKeyword(keyword);userSearch.setCreatedTime(new Date());//构造搜索条件Query query1 = Query.query(Criteria.where("userId").is(userId));query1.with(Sort.by(Sort.Direction.DESC,"createdTime"));//执行查询List<ApUserSearch> list = mongoTemplate.find(query1, ApUserSearch.class);//判断listif(list == null || list.size() < 10){mongoTemplate.save(userSearch);}else {//获取mongodb中最后一条数据就ApUserSearch apUserSearch = list.get(list.size() - 1);//findAndReplace:根据查询条件替换库中的数据mongoTemplate.findAndReplace(Query.query(Criteria.where("id").is(apUserSearch.getId())),userSearch);}}}

3、在文章搜索方法search中异步调用上面实现的保存记录方法

        注意:异步调用的方法需要在方法上加@Async 注解,并在工程启动类加入@EnableAsynczh注解开启异步

        @Async是 Spring 框架提供的注解,用于将方法标记为异步执行的方法。它的作用是告诉 Spring 框架在调用被注解的方法时,将其放入线程池中异步执行,而不是阻塞等待方法的完成。

 service层完整代码如下

package com.heima.search.service.impl;import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.search.ApUserSearch;
import com.heima.model.common.search.UserSearchDto;
import com.heima.model.common.user.ApUser;
import com.heima.search.service.ArticleSearchService;
import com.heima.utils.thread.AppThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;@Service
@Slf4j
public class ArticleSearchServiceImpl implements ArticleSearchService {@AutowiredRestHighLevelClient restHighLevelClient;@AutowiredMongoTemplate mongoTemplate;/*文章搜索*/@Overridepublic ResponseResult search(UserSearchDto dto) throws IOException {//参数校验//1.检查参数if(dto == null || StringUtils.isBlank(dto.getSearchWords())){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}ApUser user = AppThreadLocalUtil.getUser();//异步调用 保存搜索记录if(user != null && dto.getFromIndex() == 0){insert(dto.getSearchWords(), user.getId());}//2.设置查询条件SearchRequest searchRequest = new SearchRequest("app_info_article");SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//布尔查询BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//关键字的分词之后查询QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(dto.getSearchWords()).field("title").field("content").defaultOperator(Operator.OR);boolQueryBuilder.must(queryStringQueryBuilder);//查询小于mindate的数据
//        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("publishTime").lt(dto.getMinBehotTime().getTime());
//        boolQueryBuilder.filter(rangeQueryBuilder);//分页查询searchSourceBuilder.from(0);searchSourceBuilder.size(dto.getPageSize());//按照发布时间倒序查询searchSourceBuilder.sort("publishTime", SortOrder.DESC);//设置高亮  titleHighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("title");highlightBuilder.preTags("<font style='color: red; font-size: inherit;'>");highlightBuilder.postTags("</font>");searchSourceBuilder.highlighter(highlightBuilder);searchSourceBuilder.query(boolQueryBuilder);searchRequest.source(searchSourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//3.结果封装返回List<Map> list = new ArrayList<>();SearchHit[] hits = searchResponse.getHits().getHits();for (SearchHit hit : hits) {String json = hit.getSourceAsString();Map map = JSON.parseObject(json, Map.class);//处理高亮if(hit.getHighlightFields() != null && hit.getHighlightFields().size() > 0){Text[] titles = hit.getHighlightFields().get("title").getFragments();String title = org.apache.commons.lang.StringUtils.join(titles);//高亮标题map.put("h_title",title);}else {//原始标题map.put("h_title",map.get("title"));}list.add(map);}return ResponseResult.okResult(list);}/*** 保存用户搜索历史记录* @param keyword* @param userId*/@Override@Asyncpublic void insert(String keyword, Integer userId) {/*查询当前用户搜索的关键字*///构造查询条件Query query = Query.query(Criteria.where("userid").is(userId).and("keyword").is(keyword));//执行mongodb库的查询ApUserSearch userSearch = mongoTemplate.findOne(query, ApUserSearch.class);/*存在则更新创建时间重新保存*/if(userSearch != null) {userSearch.setCreatedTime(new Date());mongoTemplate.save(userSearch);return;}/*不存在,判断当前搜索记录数量是否超过10条*/userSearch = new ApUserSearch();userSearch.setUserId(userId);userSearch.setKeyword(keyword);userSearch.setCreatedTime(new Date());//构造搜索条件Query query1 = Query.query(Criteria.where("userId").is(userId));query1.with(Sort.by(Sort.Direction.DESC,"createdTime"));//执行查询List<ApUserSearch> list = mongoTemplate.find(query1, ApUserSearch.class);//判断listif(list == null || list.size() < 10){mongoTemplate.save(userSearch);}else {//获取mongodb中最后一条数据就ApUserSearch apUserSearch = list.get(list.size() - 1);//findAndReplace:根据查询条件替换库中的数据mongoTemplate.findAndReplace(Query.query(Criteria.where("id").is(apUserSearch.getId())),userSearch);}}}

4、测试

前端输入搜索内容

查看数据库mongdb中的数据成功添加

 

下一篇:Mongodb:业务应用(2)_Success___的博客-CSDN博客

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

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

相关文章

Intellij IDEA 导入 eclipse web 项目详细操作

Eclipse当中的web项目都会有这两个文件。但是idea当中应该是没有的&#xff0c;所以导入会出现兼容问题。但是本篇文章会教大家如何导入&#xff0c;并且导入过后还能使用tomcat运行。文章尽可能以图片的形式进行演示。我的idea使用的版本是2022.3.3版本。当然按正常来说版本之…

查询树形目录(内存遍历成树返回)

实体 Data TableName("dtp_sm_servicetype") ApiModel(value "SmServicetype对象", description "服务类型") EqualsAndHashCode(callSuper true) public class SmServicetype extends BaseEntity {ApiModelProperty("服务类型名称&quo…

C++ ModBUS TCP客户端工具 qModMaster 介绍及使用

qModMaster工具介绍 QModMaster是一个基于Qt的Modbus主站&#xff08;Master&#xff09;模拟器&#xff0c;用于模拟和测试Modbus TCP和RTU通信。它提供了一个直观的图形界面&#xff0c;使用户能够轻松设置和发送Modbus请求&#xff0c;并查看和分析响应数据。 以下是QModM…

图论——最短路算法

引入&#xff1a; 如上图&#xff0c;已知图G。 问节点1到节点3的最短距离。 可心算而出为d[1,2]d[2,3]112,比d[1,3]要小。 求最短路径算法&#xff1a; 1.Floyd(弗洛伊德) 是一种基于三角形不等式的多源最短路径算法。边权可以为负数 表现为a[i,j]a[j,k]<a[i,k]。 …

vue3 使用 element-china-area-data 实现地区选择器

官方地址&#xff1a;https://www.npmjs.com/package/element-china-area-data?activeTabreadme 在线示例&#xff1a;https://plortinus.github.io/element-china-area-data/index.html 实际使用 <el-col :span"12"><el-form-item label"所处城市&…

什么是响应式设计?列举几种实现响应式设计的方法。

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是响应式设计&#xff1f;⭐ 实现响应式设计的方法⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏…

Docker安装ElasticSearch/ES 7.4.0

目录 前言安装ElasticSearch/ES安装步骤1&#xff1a;准备1. 安装docker2. 搜索可以使用的镜像。3. 也可从docker hub上搜索镜像。4. 选择合适的redis镜像。 安装步骤2&#xff1a;拉取ElasticSearch镜像1 拉取镜像2 查看已拉取的镜像 安装步骤3&#xff1a;创建容器创建容器方…

android 如何分析应用的内存(十八)终章——使用Perfetto查看内存与调用栈之间的泄露

android 如何分析应用的内存&#xff08;十八&#xff09; 在前面两篇文章中&#xff0c;先是介绍了如何用AS查看Android的堆内存&#xff0c;然后介绍了使用MAT查看 Android的堆内存。AS能够满足基本的内存分析需求&#xff0c;但是无法进行多个堆的综合比较&#xff0c;因此…

ArcGIS Pro基础:【按顺序编号】工具实现属性字段的编号自动赋值

本次介绍一个字段的自动排序编号赋值工具&#xff0c;基于arcgis 的字段计算器工具也可以实现类似功能&#xff0c;但是需要自己写一段代码实现&#xff0c; 相对而言不是很方便。 如下所示&#xff0c;该工具就是【编辑】下的【属性】下的【按顺序编号】工具。 其操作方法是…

FreeRTOS(二值信号量)

资料来源于硬件家园&#xff1a;资料汇总 - FreeRTOS实时操作系统课程(多任务管理) 目录 一、信号量的概念 1、信号量的基本概念 2、信号量的分类 二、二值信号量的定义与应用 1、二值信号量的定义 2、二值信号量的应用 三、二值信号量的运作机制 1、FreeRTOS任务间二值…

可视化绘图技巧100篇基础篇(二)-柱状图

目录 前言 什么是柱状图 柱状图的组成 使用场景 适用场景: 不适用场景:

Spring Web

◆ Spring整合web环境 - Javaweb三大组件及环境特点 - Spring整合web环境的思路及实现 把ApplicationContext放在ServleContent域【listen组件中】中 ContextLoaderListener &#xff1a;部分代码写死了 /*** 配置通用的Spring容器的创建&#xff0c;只需要创建一次就可以*/…

hackrf-faq-1

Getting Help — HackRF documentation HackRF Product Line - Great Scott Gadgets Software Defined Radio with HackRF - Great Scott Gadgets What is the Transmit Power of HackRF? HackRF One’s absolute maximum TX power varies by operating frequency: 1 MHz t…

SQL server 与 MySQL count函数、以及sum、avg 是否包含 为null的值

sql server 与 mysql count 作用一样。 count 计算指定字段出现的个数&#xff0c; 不是计算 null的值 获取表的条数 count(n) n:常数 count(1),count&#xff08;0&#xff09;等 count(*) count(字段) 其中字段为null 不会统计在内。 avg(字段)、sum(字段) 跟count(字段)…

科技资讯|苹果手机版Vision Pro头显专利曝光,内嵌苹果手机使用

根据美国商标和专利局&#xff08;USPTO&#xff09;公示的清单&#xff0c;苹果公司近日获得了一项头显相关的技术专利&#xff0c;展示了一款亲民款 Vision Pro 头显&#xff0c;可以将 iPhone 放置在头显内部充当屏幕。 根据patentlyapple 媒体报道&#xff0c;这是苹果公司…

案例12 Spring MVC入门案例

网页输入http://localhost:8080/hello&#xff0c;浏览器展示“Hello Spring MVC”。 1. 创建项目 选择Maven快速构建web项目&#xff0c;项目名称为case12-springmvc01。 2.配置Maven依赖 <?xml version"1.0" encoding"UTF-8"?><project xm…

【计算机网络】TCP协议超详细讲解

文章目录 1. TCP简介2. TCP和UDP的区别3. TCP的报文格式4. 确认应答机制5. 超时重传6. 三次握手7. 为什么两次握手不行?8. 四次挥手9. 滑动窗口10. 流量控制11. 拥塞控制12. 延时应答13. 捎带应答14. 面向字节流15. TCP的连接异常处理 1. TCP简介 TCP协议广泛应用于可靠性要求…

Mybatis动态SQL,标签大全

动态SQL常用场景 批量删除delete from t_car where id in(1,2,3,4,5,6,......这里的值是动态的&#xff0c;根据用户选择的 id不同&#xff0c;值是不同的);多条件查询哪些字段会作为查询条件是不确定的&#xff0c;根据用户而定 select * from 1 t_car where brand like 丰田…

IP 协议的相关特性和数据链路层相关知识总结

目录 IP 协议的相关特性 一、IP协议的特性 二、 IP协议数据报格式 三、 IP协议的主要功能 1. 地址管理 动态分配 IP地址 NAT机制 NAT背景下的通信 IPV6 2. 路由控制​​​​​​​ 3.IP报文的分片与重组 数据链路层相关知识 1、以太网协议&#xff08;Ethernet&#xff09; 2.M…

C#Winform中DataGridView单元格Header背景颜色设置

C#Winform中DataGridView单元格Header背景颜色设置属性 //设置包含Header所有的单元格的背景色 DataGridView1.DefaultCellStyle.BackColor = Color.Red; //设置包含Header所有的单元格的前景色 DataGridView1.DefaultCellStyle.ForeColor= Color.Red; //设置 Header以外所有…