保存搜索记录
一、实现思路
输入关键字——》搜索——异步请求——》记录关键字
【异步请求保存关键字,让用户快速看到搜索结果,等待时间更短】
保存——>查询搜索记录——存在——更新到最新时间
不存在——搜索记录的数量是否超过10——没超过则直接保存,超过则替换最后一条数据即时间最久
二、实现步骤
1、搜索微服务集成mongodb
pom依赖
nacos配置
创建对应实体类
<!--mongoDB--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
server: port: 9998 spring: data: mongodb: host: 192.168.200.130 port: 27017 database: leadnews-history
2、创建ApUserSearchService新增insert方法
查询当前用户搜索的关键词是否存在
存在则更新最新时间
不存在则新增, 判断当前历史记录是否超过10条记录
package com.heima.search.service.impl; import com.heima.search.pojos.ApUserSearch; import com.heima.search.service.ApUserSearchService; 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.stereotype.Service; import java.util.Date; import java.util.List; @Service @Slf4j public class ApUserSearchServiceImpl implements ApUserSearchService { @Autowired private MongoTemplate mongoTemplate; /** * 保存用户搜索历史记录 * * @param keyword * @param userId */ @Override public void insert(String keyword, Integer userId) { //1、查询当前用户搜索关键词 Query query = Query.query(Criteria.where("userId").is(userId).and("keyword").is(keyword)); ApUserSearch apUserSearch = mongoTemplate.findOne(query, ApUserSearch.class); //用户搜索信息表 //2、存在更新创建时间 if(apUserSearch != null){ apUserSearch.setCreatedTime(new Date()); mongoTemplate.save(apUserSearch); return; } //3、不存在,判断当前历史记录总数是否超过10 apUserSearch = new ApUserSearch(); apUserSearch.setUserId(userId); apUserSearch.setKeyword(keyword); apUserSearch.setCreatedTime(new Date()); Query query1 = Query.query(Criteria.where("userId").is(userId)); query1.with(Sort.by(Sort.Direction.DESC, "createdTime")); List<ApUserSearch> apUserSearches = mongoTemplate.find(query1, ApUserSearch.class); if(apUserSearches == null || apUserSearches.size() < 10){ mongoTemplate.save(apUserSearch); }else{ ApUserSearch lastUserSearch = apUserSearches.get(apUserSearches.size() - 1); mongoTemplate.findAndReplace(Query.query(Criteria.where("id").is(lastUserSearch.getId())), apUserSearch); } } }
3、参考自媒体相关微服务,在搜索微服务中获取当前登录的用户【ThreadLocal、Interceptor】
在app网关中把用户id存入header
//获取用户信息 Object userId = claimsBody.get("id"); //存入header ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> { httpHeaders.add("userId", userId + ""); }).build(); //重置请求 exchange.mutate().request(serverHttpRequest);
在interceptor中获取id存在Threadlocal
package com.heima.utils.common.thread; import com.heima.model.user.pojos.ApUser; import com.heima.model.wemedia.pojos.WmUser; public class AppThreadLocalUtil { public final static ThreadLocal<ApUser> WM_USER_THREAD_LOCAL = new ThreadLocal<>(); //存入线程 public static void setUser(ApUser apUser){ WM_USER_THREAD_LOCAL.set(apUser); } //从线程中获取 public static ApUser getUser(){ return WM_USER_THREAD_LOCAL.get(); } //清理 public static void clear(){ WM_USER_THREAD_LOCAL.remove(); } }
package com.heima.search.interceptor; import com.heima.model.user.pojos.ApUser; import com.heima.model.wemedia.pojos.WmUser; import com.heima.utils.common.thread.AppThreadLocalUtil; import com.heima.utils.common.thread.WmThreadLocalUtil; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AppTokenInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String userId = request.getHeader("userId"); if(userId != null){ //存入当前线程 ApUser apUser = new ApUser(); apUser.setId(Integer.valueOf(userId)); AppThreadLocalUtil.setUser(apUser); } return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { AppThreadLocalUtil.clear(); } }
package com.heima.search.config; import com.heima.search.interceptor.AppTokenInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AppTokenInterceptor()).addPathPatterns("/**"); } }
4、在ArticleSearchService的search方法中调用保存历史记录
ApUser user = AppThreadLocalUtil.getUser(); //异步调用保存搜索记录:不登录不能保存, 搜索词首页才保存搜索历史 if(user != null && dto.getFromIndex() == 0){ apUserSearchService.insert(dto.getSearchWords(), user.getId()); }
5、保存历史记录中开启异步调用,添加注解@Async
6、在搜索微服务引导类上开启异步调用
7.测试,搜索后查看结果