当前位置: 首页 > news >正文

网站建设适合什么单位绍兴市住房与城乡建设厅网站

网站建设适合什么单位,绍兴市住房与城乡建设厅网站,网店装修网站,互联网推广有哪些方式本笔记内容为黑马头条项目的app端文章搜索部分 目录 一、今日内容介绍 1、App端搜索-效果图 2、今日内容 二、搭建ElasticSearch环境 1、拉取镜像 2、创建容器 3、配置中文分词器 ik 4、使用postman测试 三、app端文章搜索 1、需求分析 2、思路分析 3、创建索引和…本笔记内容为黑马头条项目的app端文章搜索部分 目录 一、今日内容介绍 1、App端搜索-效果图 2、今日内容 二、搭建ElasticSearch环境 1、拉取镜像 2、创建容器 3、配置中文分词器 ik 4、使用postman测试 三、app端文章搜索 1、需求分析 2、思路分析 3、创建索引和映射 4、数据初始化到索引库 5、文章搜索功能实现 6、文章自动审核构建索引 四、app端搜索-搜索记录 1、需求分析 2、数据存储说明 3、MongoDB安装及集成 4、保存搜索记录 5、加载搜索记录列表 6、删除搜索记录 五、app端搜索-关键字联想词 1、需求分析 2、搜索词-数据来源 3、功能实现 一、今日内容介绍 1、App端搜索-效果图 2、今日内容 文章搜索 ElasticSearch环境搭建 索引库创建 文章搜索多条件复合查询 索引数据同步 搜索历史记录 Mongodb环境搭建 异步保存搜索历史 查看搜索历史列表 删除搜索历史 联想词查询 联想词的来源 联想词功能实现 二、搭建ElasticSearch环境 1、拉取镜像 docker pull elasticsearch:7.4.0 2、创建容器 docker run -id --name elasticsearch -d --restartalways -p 9200:9200 -p 9300:9300 -v /usr/share/elasticsearch/plugins:/usr/share/elasticsearch/plugins -e discovery.typesingle-node elasticsearch:7.4.0 3、配置中文分词器 ik 因为在创建elasticsearch容器的时候映射了目录所以可以在宿主机上进行配置ik中文分词器 在去选择ik分词器的时候需要与elasticsearch的版本好对应上 把资料中的elasticsearch-analysis-ik-7.4.0.zip上传到服务器上,放到对应目录plugins解压 #切换目录 cd /usr/share/elasticsearch/plugins #新建目录 mkdir analysis-ik cd analysis-ik #root根目录中拷贝文件 mv elasticsearch-analysis-ik-7.4.0.zip /usr/share/elasticsearch/plugins/analysis-ik #解压文件 cd /usr/share/elasticsearch/plugins/analysis-ik unzip elasticsearch-analysis-ik-7.4.0.zip 4、使用postman测试 三、app端文章搜索 1、需求分析 用户输入关键可搜索文章列表 关键词高亮显示 文章列表展示与home展示一样当用户点击某一篇文章可查看文章详情 2、思路分析 为了加快检索的效率在查询的时候不会直接从数据库中查询文章需要在elasticsearch中进行高速检索。 3、创建索引和映射 使用postman添加映射 put请求 http://192.168.200.130:9200/app_info_article {mappings:{properties:{id:{type:long},publishTime:{type:date},layout:{type:integer},images:{type:keyword,index: false},staticUrl:{type:keyword,index: false},authorId: {type: long},authorName: {type: text},title:{type:text,analyzer:ik_smart},content:{type:text,analyzer:ik_smart}}} } 4、数据初始化到索引库 1.导入es-init到heima-leadnews-test工程下 2.查询所有的文章信息批量导入到es索引库中 package com.heima.es;import com.alibaba.fastjson.JSON; import com.heima.es.mapper.ApArticleMapper; import com.heima.es.pojo.SearchArticleVo; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;import java.util.List;SpringBootTest RunWith(SpringRunner.class) public class ApArticleTest {Autowiredprivate ApArticleMapper apArticleMapper;Autowiredprivate RestHighLevelClient restHighLevelClient;/*** 注意数据量的导入如果数据量过大需要分页导入* throws Exception*/Testpublic void init() throws Exception {//1.查询所有符合条件的文章数据ListSearchArticleVo searchArticleVos apArticleMapper.loadArticleList();//2.批量导入到es索引库BulkRequest bulkRequest new BulkRequest(app_info_article);for (SearchArticleVo searchArticleVo : searchArticleVos) {IndexRequest indexRequest new IndexRequest().id(searchArticleVo.getId().toString()).source(JSON.toJSONString(searchArticleVo), XContentType.JSON);//批量添加数据bulkRequest.add(indexRequest);}restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);}} 3.测试 postman查询所有的es中数据 GET请求 http://192.168.200.130:9200/app_info_article/_search 5、文章搜索功能实现 1.搭建搜索微服务 ①导入 heima-leadnews-search ②在heima-leadnews-service的pom中添加依赖 !--elasticsearch-- dependencygroupIdorg.elasticsearch.client/groupIdartifactIdelasticsearch-rest-high-level-client/artifactIdversion7.4.0/version /dependency dependencygroupIdorg.elasticsearch.client/groupIdartifactIdelasticsearch-rest-client/artifactIdversion7.4.0/version /dependency dependencygroupIdorg.elasticsearch/groupIdartifactIdelasticsearch/artifactIdversion7.4.0/version /dependency ③nacos配置中心leadnews-search spring:autoconfigure:exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration elasticsearch:host: 192.168.200.130port: 9200 2.搜索接口定义 package com.heima.search.controller.v1;import com.heima.model.common.dtos.ResponseResult; import com.heima.model.search.dtos.UserSearchDto; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException;RestController RequestMapping(/api/v1/article/search) public class ArticleSearchController {PostMapping(/search)public ResponseResult search(RequestBody UserSearchDto dto) throws IOException {return null;} }UserSearchDto package com.heima.model.search.dtos;import lombok.Data;import java.util.Date;Data public class UserSearchDto {/*** 搜索关键字*/String searchWords;/*** 当前页*/int pageNum;/*** 分页条数*/int pageSize;/*** 最小时间*/Date minBehotTime;public int getFromIndex(){if(this.pageNum1)return 0;if(this.pageSize1) this.pageSize 10;return this.pageSize * (pageNum-1);} } 3.业务层实现 创建业务层接口ApArticleSearchService package com.heima.search.service;import com.heima.model.search.dtos.UserSearchDto; import com.heima.model.common.dtos.ResponseResult;import java.io.IOException;public interface ArticleSearchService {/**ES文章分页搜索return*/ResponseResult search(UserSearchDto userSearchDto) throws IOException; } 实现类 package com.heima.search.service.impl;import com.alibaba.fastjson.JSON; import com.heima.model.common.dtos.ResponseResult; import com.heima.model.common.enums.AppHttpCodeEnum; import com.heima.model.search.dtos.UserSearchDto; import com.heima.model.user.pojos.ApUser; import com.heima.search.service.ArticleSearchService; import com.heima.utils.thread.AppThreadLocalUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; 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.stereotype.Service;import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map;Service Slf4j public class ArticleSearchServiceImpl implements ArticleSearchService {Autowiredprivate RestHighLevelClient restHighLevelClient;/*** es文章分页检索** param dto* return*/Overridepublic ResponseResult search(UserSearchDto dto) throws IOException {//1.检查参数if(dto null || StringUtils.isBlank(dto.getSearchWords())){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}//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 stylecolor: red; font-size: inherit;);highlightBuilder.postTags(/font);searchSourceBuilder.highlighter(highlightBuilder);searchSourceBuilder.query(boolQueryBuilder);searchRequest.source(searchSourceBuilder);SearchResponse searchResponse restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//3.结果封装返回ListMap 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 StringUtils.join(titles);//高亮标题map.put(h_title,title);}else {//原始标题map.put(h_title,map.get(title));}list.add(map);}return ResponseResult.okResult(list);} } 4.控制层实现 新建控制器ArticleSearchController package com.heima.search.controller.v1;import com.heima.model.common.dtos.ResponseResult; import com.heima.model.search.dtos.UserSearchDto; import com.heima.search.service.ArticleSearchService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.io.IOException;RestController RequestMapping(/api/v1/article/search) public class ArticleSearchController {Autowiredprivate ArticleSearchService articleSearchService;PostMapping(/search)public ResponseResult search(RequestBody UserSearchDto dto) throws IOException {return articleSearchService.search(dto);} } 5.测试 需要在app的网关中添加搜索微服务的路由配置 #搜索微服务 - id: leadnews-searchuri: lb://leadnews-searchpredicates:- Path/search/**filters:- StripPrefix 1 启动项目进行测试至少要启动文章微服务用户微服务搜索微服务app网关微服务app前端工程 6、文章自动审核构建索引 1.思路分析 2.文章微服务发送消息 ①把SearchArticleVo放到model工程下 package com.heima.model.search.vos;import lombok.Data;import java.util.Date;Data public class SearchArticleVo {// 文章idprivate Long id;// 文章标题private String title;// 文章发布时间private Date publishTime;// 文章布局private Integer layout;// 封面private String images;// 作者idprivate Long authorId;// 作者名词private String authorName;//静态urlprivate String staticUrl;//文章内容private String content;} ②文章微服务的ArticleFreemarkerService中的buildArticleToMinIO方法中收集数据并发送消息 完整代码如下 package com.heima.article.service.impl;import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.heima.article.mapper.ApArticleContentMapper; import com.heima.article.service.ApArticleService; import com.heima.article.service.ArticleFreemarkerService; import com.heima.common.constants.ArticleConstants; import com.heima.file.service.FileStorageService; import com.heima.model.article.pojos.ApArticle; import com.heima.model.search.vos.SearchArticleVo; import freemarker.template.Configuration; import freemarker.template.Template; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import java.util.HashMap; import java.util.Map;Service Slf4j Transactional public class ArticleFreemarkerServiceImpl implements ArticleFreemarkerService {Autowiredprivate ApArticleContentMapper apArticleContentMapper;Autowiredprivate Configuration configuration;Autowiredprivate FileStorageService fileStorageService;Autowiredprivate ApArticleService apArticleService;/*** 生成静态文件上传到minIO中* param apArticle* param content*/AsyncOverridepublic void buildArticleToMinIO(ApArticle apArticle, String content) {//已知文章的id//4.1 获取文章内容if(StringUtils.isNotBlank(content)){//4.2 文章内容通过freemarker生成html文件Template template null;StringWriter out new StringWriter();try {template configuration.getTemplate(article.ftl);//数据模型MapString,Object contentDataModel new HashMap();contentDataModel.put(content, JSONArray.parseArray(content));//合成template.process(contentDataModel,out);} catch (Exception e) {e.printStackTrace();}//4.3 把html文件上传到minio中InputStream in new ByteArrayInputStream(out.toString().getBytes());String path fileStorageService.uploadHtmlFile(, apArticle.getId() .html, in);//4.4 修改ap_article表保存static_url字段apArticleService.update(Wrappers.ApArticlelambdaUpdate().eq(ApArticle::getId,apArticle.getId()).set(ApArticle::getStaticUrl,path));//发送消息创建索引createArticleESIndex(apArticle,content,path);}}Autowiredprivate KafkaTemplateString,String kafkaTemplate;/*** 送消息创建索引* param apArticle* param content* param path*/private void createArticleESIndex(ApArticle apArticle, String content, String path) {SearchArticleVo vo new SearchArticleVo();BeanUtils.copyProperties(apArticle,vo);vo.setContent(content);vo.setStaticUrl(path);kafkaTemplate.send(ArticleConstants.ARTICLE_ES_SYNC_TOPIC, JSON.toJSONString(vo));}} 在ArticleConstants类中添加新的常量完整代码如下 package com.heima.common.constants;public class ArticleConstants {public static final Short LOADTYPE_LOAD_MORE 1;public static final Short LOADTYPE_LOAD_NEW 2;public static final String DEFAULT_TAG __all__;public static final String ARTICLE_ES_SYNC_TOPIC article.es.sync.topic;public static final Integer HOT_ARTICLE_LIKE_WEIGHT 3;public static final Integer HOT_ARTICLE_COMMENT_WEIGHT 5;public static final Integer HOT_ARTICLE_COLLECTION_WEIGHT 8;public static final String HOT_ARTICLE_FIRST_PAGE hot_article_first_page_; } ③文章微服务集成kafka发送消息 在文章微服务的nacos的配置中心添加如下配置 kafka:bootstrap-servers: 192.168.200.130:9092producer:retries: 10key-serializer: org.apache.kafka.common.serialization.StringSerializervalue-serializer: org.apache.kafka.common.serialization.StringSerializer 3.搜索微服务创建索引 ①搜索微服务中添加kafka的配置,nacos配置如下 spring:kafka:bootstrap-servers: 192.168.200.130:9092consumer:group-id: ${spring.application.name}key-deserializer: org.apache.kafka.common.serialization.StringDeserializervalue-deserializer: org.apache.kafka.common.serialization.StringDeserializer ②定义监听接收消息,保存索引数据 package com.heima.search.listener;import com.alibaba.fastjson.JSON; import com.heima.common.constants.ArticleConstants; import com.heima.model.search.vos.SearchArticleVo; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Component;import java.io.IOException;Component Slf4j public class SyncArticleListener {Autowiredprivate RestHighLevelClient restHighLevelClient;KafkaListener(topics ArticleConstants.ARTICLE_ES_SYNC_TOPIC)public void onMessage(String message){if(StringUtils.isNotBlank(message)){log.info(SyncArticleListener,message{},message);SearchArticleVo searchArticleVo JSON.parseObject(message, SearchArticleVo.class);IndexRequest indexRequest new IndexRequest(app_info_article);indexRequest.id(searchArticleVo.getId().toString());indexRequest.source(message, XContentType.JSON);try {restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);} catch (IOException e) {e.printStackTrace();log.error(sync es error{},e);}}} } 四、app端搜索-搜索记录 1、需求分析 2、数据存储说明 用户的搜索记录需要给每一个用户都保存一份数据量较大要求加载速度快通常这样的数据存储到mongodb更合适不建议直接存储到关系型数据库中 3、MongoDB安装及集成 1.安装MongoDB 拉取镜像 docker pull mongo 创建容器 docker run -di --name mongo-service --restartalways -p 27017:27017 -v ~/data/mongodata:/data mongo 2.导入资料中的mongo-demo项目到heima-leadnews-test中 其中有三项配置比较关键 第一mongo依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-mongodb/artifactId /dependency 第二mongo配置 server:port: 9998 spring:data:mongodb:host: 192.168.200.130port: 27017database: leadnews-history 第三映射 package com.itheima.mongo.pojo;import lombok.Data; import org.springframework.data.mongodb.core.mapping.Document;import java.io.Serializable; import java.util.Date;/*** p* 联想词表* /p** author itheima*/ Data Document(ap_associate_words) public class ApAssociateWords implements Serializable {private static final long serialVersionUID 1L;private String id;/*** 联想词*/private String associateWords;/*** 创建时间*/private Date createdTime;} 3.核心方法 package com.itheima.mongo.test;import com.itheima.mongo.MongoApplication; import com.itheima.mongo.pojo.ApAssociateWords; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; 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.test.context.junit4.SpringRunner;import java.util.Date; import java.util.List;SpringBootTest(classes MongoApplication.class) RunWith(SpringRunner.class) public class MongoTest {Autowiredprivate MongoTemplate mongoTemplate;//保存Testpublic void saveTest(){/*for (int i 0; i 10; i) {ApAssociateWords apAssociateWords new ApAssociateWords();apAssociateWords.setAssociateWords(黑马头条);apAssociateWords.setCreatedTime(new Date());mongoTemplate.save(apAssociateWords);}*/ApAssociateWords apAssociateWords new ApAssociateWords();apAssociateWords.setAssociateWords(黑马直播);apAssociateWords.setCreatedTime(new Date());mongoTemplate.save(apAssociateWords);}//查询一个Testpublic void saveFindOne(){ApAssociateWords apAssociateWords mongoTemplate.findById(60bd973eb0c1d430a71a7928, ApAssociateWords.class);System.out.println(apAssociateWords);}//条件查询Testpublic void testQuery(){Query query Query.query(Criteria.where(associateWords).is(黑马头条)).with(Sort.by(Sort.Direction.DESC,createdTime));ListApAssociateWords apAssociateWordsList mongoTemplate.find(query, ApAssociateWords.class);System.out.println(apAssociateWordsList);}Testpublic void testDel(){mongoTemplate.remove(Query.query(Criteria.where(associateWords).is(黑马头条)),ApAssociateWords.class);} } 4、保存搜索记录 1.实现思路 用户输入关键字进行搜索的异步记录关键字 用户搜索记录对应的集合对应实体类 package com.heima.search.pojos;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;} 2.实现步骤 ①搜索微服务集成mongodb pom依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-mongodb/artifactId /dependency nacos配置 spring:data:mongodb:host: 192.168.200.130port: 27017database: leadnews-history 在当天资料中找到对应的实体类拷贝到搜索微服务下 package com.heima.search.pojos;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;} package com.heima.search.pojos;import lombok.Data; import org.springframework.data.mongodb.core.mapping.Document;import java.io.Serializable; import java.util.Date;/*** p* 联想词表* /p** author itheima*/ Data Document(ap_associate_words) public class ApAssociateWords implements Serializable {private static final long serialVersionUID 1L;private String id;/*** 联想词*/private String associateWords;/*** 创建时间*/private Date createdTime;} ②创建ApUserSearchService新增insert方法 public interface ApUserSearchService {/*** 保存用户搜索历史记录* param keyword* param userId*/public void insert(String keyword,Integer userId); } 实现类 Service Slf4j public class ApUserSearchServiceImpl implements ApUserSearchService {Autowiredprivate MongoTemplate mongoTemplate;/*** 保存用户搜索历史记录* param keyword* param userId*/OverrideAsyncpublic 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.不存在判断当前历史记录总数量是否超过10apUserSearch 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));ListApUserSearch apUserSearchList mongoTemplate.find(query1, ApUserSearch.class);if(apUserSearchList null || apUserSearchList.size() 10){mongoTemplate.save(apUserSearch);}else {ApUserSearch lastUserSearch apUserSearchList.get(apUserSearchList.size() - 1);mongoTemplate.findAndReplace(Query.query(Criteria.where(id).is(lastUserSearch.getId())),apUserSearch);}} } 3.参考自媒体相关微服务在搜索微服务中获取当前登录的用户 Util类 package com.heima.utils.thread;import com.heima.model.user.pojos.ApUser; import com.heima.model.wemedia.pojos.WmUser;/*** Description: new java files header..** author zhangzuhao* version 1.0* date 2023/7/18 15:56*/public class AppThreadLocalUtil {private final static ThreadLocalApUser 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();} } interceptor package com.heima.search.interceptor;import com.heima.model.user.pojos.ApUser; import com.heima.model.wemedia.pojos.WmUser; import com.heima.utils.thread.AppThreadLocalUtil; import com.heima.utils.thread.WmThreadLocalUtil; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** Description: new java files header..** author zhangzuhao* version 1.0* date 2023/8/7 16:54*/public class AppTokenInterceptor implements HandlerInterceptor {Overridepublic 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;}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {AppThreadLocalUtil.clear();} }config 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;/*** Description: new java files header..** author zhangzuhao* version 1.0* date 2023/7/18 16:06*/Configuration public class WebMvcConfig implements WebMvcConfigurer {Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AppTokenInterceptor()).addPathPatterns(/**);} }4.在ArticleSearchService的search方法中调用保存历史记录 完整代码如下 package com.heima.search.service.impl;import com.alibaba.fastjson.JSON; import com.heima.model.common.dtos.ResponseResult; import com.heima.model.common.enums.AppHttpCodeEnum; import com.heima.model.search.dtos.UserSearchDto; import com.heima.model.user.pojos.ApUser; import com.heima.search.service.ApUserSearchService; import com.heima.search.service.ArticleSearchService; import com.heima.utils.thread.AppThreadLocalUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; 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.stereotype.Service;import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map;Service Slf4j public class ArticleSearchServiceImpl implements ArticleSearchService {Autowiredprivate RestHighLevelClient restHighLevelClient;Autowiredprivate ApUserSearchService apUserSearchService;/*** es文章分页检索** param dto* return*/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){apUserSearchService.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 stylecolor: red; font-size: inherit;);highlightBuilder.postTags(/font);searchSourceBuilder.highlighter(highlightBuilder);searchSourceBuilder.query(boolQueryBuilder);searchRequest.source(searchSourceBuilder);SearchResponse searchResponse restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//3.结果封装返回ListMap 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 StringUtils.join(titles);//高亮标题map.put(h_title,title);}else {//原始标题map.put(h_title,map.get(title));}list.add(map);}return ResponseResult.okResult(list);} } 5.保存历史记录中开启异步调用添加注解Async 6.在搜索微服务引导类上开启异步调用 7.测试搜索后查看结果 5、加载搜索记录列表 1.思路分析 按照当前用户按照时间倒序查询 说明接口路径/api/v1/history/load请求方式POST参数无响应结果ResponseResult 2.接口定义 /*** p* APP用户搜索信息表 前端控制器* /p** author itheima*/ Slf4j RestController RequestMapping(/api/v1/history) public class ApUserSearchController{PostMapping(/load)Overridepublic ResponseResult findUserSearch() {return null;}} 3.mapper 已定义 4.业务层 在ApUserSearchService中新增方法 /**查询搜索历史return*/ ResponseResult findUserSearch(); 实现方法 /*** 查询搜索历史** return*/ Override public ResponseResult findUserSearch() {//获取当前用户ApUser user AppThreadLocalUtil.getUser();if(user null){return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);}//根据用户查询数据按照时间倒序ListApUserSearch apUserSearches mongoTemplate.find(Query.query(Criteria.where(userId).is(user.getId())).with(Sort.by(Sort.Direction.DESC, createdTime)), ApUserSearch.class);return ResponseResult.okResult(apUserSearches); } 5.控制器 /*** p* APP用户搜索信息表 前端控制器* /p* author itheima*/ Slf4j RestController RequestMapping(/api/v1/history) public class ApUserSearchController{Autowiredprivate ApUserSearchService apUserSearchService;PostMapping(/load)public ResponseResult findUserSearch() {return apUserSearchService.findUserSearch();}} 6.测试 打开app的搜索页面可以查看搜索记录列表 6、删除搜索记录 1.思路分析 按照搜索历史id删除 说明接口路径/api/v1/history/del请求方式POST参数HistorySearchDto响应结果ResponseResult 2.接口定义 在ApUserSearchController接口新增方法 PostMapping(/del) public ResponseResult delUserSearch(RequestBody HistorySearchDto historySearchDto) {return null; } HistorySearchDto Data public class HistorySearchDto {/*** 接收搜索历史记录id*/String id; } 3.业务层 在ApUserSearchService中新增方法 /**删除搜索历史param historySearchDtoreturn*/ ResponseResult delUserSearch(HistorySearchDto historySearchDto); 实现方法 /*** 删除历史记录** param dto* return*/ Override public ResponseResult delUserSearch(HistorySearchDto dto) {//1.检查参数if(dto.getId() null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}//2.判断是否登录ApUser user AppThreadLocalUtil.getUser();if(user null){return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);}//3.删除mongoTemplate.remove(Query.query(Criteria.where(userId).is(user.getId()).and(id).is(dto.getId())),ApUserSearch.class);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS); } 4.控制器 修改ApUserSearchController补全方法 PostMapping(/del) public ResponseResult delUserSearch(RequestBody HistorySearchDto historySearchDto) {return apUserSearchService.delUserSearch(historySearchDto); } 5.测试 打开app可以删除搜索记录 五、app端搜索-关键字联想词 1、需求分析 对应实体类 package com.heima.search.pojos;import lombok.Data; import org.springframework.data.mongodb.core.mapping.Document;import java.io.Serializable; import java.util.Date;/*** p* 联想词表* /p** author itheima*/ Data Document(ap_associate_words) public class ApAssociateWords implements Serializable {private static final long serialVersionUID 1L;private String id;/*** 联想词*/private String associateWords;/*** 创建时间*/private Date createdTime;} 2、搜索词-数据来源 通常是网上搜索频率比较高的一些词通常在企业中有两部分来源 第一自己维护搜索词 通过分析用户搜索频率较高的词按照排名作为搜索词 第二第三方获取 关键词规划师百度、5118、爱站网 3、功能实现 1.接口定义 说明接口路径/api/v1/associate/search请求方式POST参数UserSearchDto响应结果ResponseResult 新建接口 package com.heima.search.controller.v1;import com.heima.model.common.dtos.ResponseResult; import com.heima.model.search.dtos.UserSearchDto; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController RequestMapping(/api/v1/associate) public class ApAssociateWordsController {PostMapping(/search)public ResponseResult search(RequestBody UserSearchDto userSearchDto) {return null;} }2.业务层 新建联想词业务层接口 package com.heima.search.service;import com.heima.model.common.dtos.ResponseResult; import com.heima.model.search.dtos.UserSearchDto;/*** p* 联想词表 服务类* /p** author itheima*/ public interface ApAssociateWordsService {/**联想词param userSearchDtoreturn*/ResponseResult findAssociate(UserSearchDto userSearchDto);} 实现类 package com.heima.search.service.impl;import com.heima.model.common.dtos.ResponseResult; import com.heima.model.common.enums.AppHttpCodeEnum; import com.heima.model.search.dtos.UserSearchDto; import com.heima.search.pojos.ApAssociateWords; import com.heima.search.service.ApAssociateWordsService; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; 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.List;/*** Description:* Version: V1.0*/ Service public class ApAssociateWordsServiceImpl implements ApAssociateWordsService {AutowiredMongoTemplate mongoTemplate;/*** 联想词* param userSearchDto* return*/Overridepublic ResponseResult findAssociate(UserSearchDto userSearchDto) {//1 参数检查if(userSearchDto null || StringUtils.isBlank(userSearchDto.getSearchWords())){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);}//分页检查if (userSearchDto.getPageSize() 20) {userSearchDto.setPageSize(20);}//3 执行查询 模糊查询Query query Query.query(Criteria.where(associateWords).regex(.*?\\ userSearchDto.getSearchWords() .*));query.limit(userSearchDto.getPageSize());ListApAssociateWords wordsList mongoTemplate.find(query, ApAssociateWords.class);return ResponseResult.okResult(wordsList);} } 3.控制器 新建联想词控制器 package com.heima.search.controller.v1;import com.heima.model.common.dtos.ResponseResult; import com.heima.model.search.dtos.UserSearchDto; import com.heima.search.service.ApAssociateWordsService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;/*** p* 联想词表 前端控制器* /p* author itheima*/ Slf4j RestController RequestMapping(/api/v1/associate) public class ApAssociateWordsController{Autowiredprivate ApAssociateWordsService apAssociateWordsService;PostMapping(/search)public ResponseResult findAssociate(RequestBody UserSearchDto userSearchDto) {return apAssociateWordsService.findAssociate(userSearchDto);} } 4.测试 同样打开前端联调测试效果 结束!
http://www.hkea.cn/news/14520840/

相关文章:

  • 常用的建站软件有哪些做公司网站要钱吗
  • 手机网站生产app市场调研报告范文模板word
  • 株洲企业网站建设工作专门做正品的网站手机版
  • 泾川县建设局网站网站建设捌金手指花总十三
  • 淘口令微信网站怎么做互联网网站解决方案
  • 做一个交易网站要花多少钱修改wordpress登录路径
  • 最好的淘宝网站建设python可以用来干什么
  • 岱山建设网站小程序定制开发公司前十名
  • 中小学网站模板源码深圳网站设计招聘网
  • 沈阳企业网站安卓app下载安装
  • 深圳网站建设可以吗深圳市做网站建设
  • vs2010网站开发 视频网站建设南阳
  • 手机网站建设专家网站地图的重要性
  • 网站备案信息查询系统WordPress静态文件存储
  • 深圳市宝安区网站建设阿里云php做网站
  • 如何做公司企业网站石景山手机网站建设
  • 仙桃市建设局网站织梦怎么做企业网站
  • 苍溪网站建设制作网站模板编辑软件
  • 旅游景点网站建设规划书中国建筑app免费下载
  • 制作网站的公司怎么样网站受到攻击怎么办
  • 网站定制制作公司深圳市品牌网站建设
  • 采购网站平台中国十大网络科技公司排名
  • 石家庄建设局中山seo推广优化
  • 营口门户网站建设dedecms旅游网站模板
  • 购物网站怎么做推广股票订阅网站开发
  • 北京优秀的网站建设公司上海网络建站模板
  • 电商网站房地产信息网查询系统
  • 学校网站建设项目需求报告网站文站加入别人网站的链接是否对自己网站不好
  • 织梦高清电影网站模板平台营销
  • 网站跳转微信链接知更鸟wordpress主题下载