Sea-Search03总结&&un finish
使用到的设计模式
Facade门面模式
为何使用?
在搜索项目中,由于使用Mvc架构且数据库中各种不同类型的数据源并没有放在同一张表,于是我们不可避免的在Controller中需要注入多个service,各种service眼花缭乱,而搜索中台提供的内容又及其单一(只负责返回搜索数据),于是采用Facade来统一接口以及装载service
代码呈现
需要注意的是,我们还需要一个统一的return对象(SearchVo),有两种思路:
- SearchVo声明成接口,由其他如PostVo来实现
- 直接聚合:SearchVo聚合各个如PostVo的内容(对于内容我们也可采用抽象类来实现)等
@Component
public class SearchFacade {
@Autowired
private PictureService pictureService;
@Autowired
private PostService postService;
@Autowired
private UserService userService;
@Autowired
private DataSourceRegistry dataSourceRegistry;
public SearchVo getAll(SearchQueryRequest searchQueryRequest, HttpServletRequest request) {
long current = searchQueryRequest.getCurrent();
long size = searchQueryRequest.getPageSize();
String searchText = searchQueryRequest.getSearchText();
String type = searchQueryRequest.getType();
SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(type);
ThrowUtils.throwIf(type != null && StringUtils.isBlank(type), ErrorCode.PARAMS_ERROR);
SearchVo searchVo = new SearchVo();
if (searchTypeEnum == null) {
CompletableFuture<Void> picCF = CompletableFuture.runAsync(() -> {
List<Picture> pictures = pictureService.searchPicture(searchQueryRequest.getSearchText(), searchQueryRequest.getCurrent(), searchQueryRequest.getPageSize());
searchVo.setPicList(pictures);
});
CompletableFuture<Void> userCF = CompletableFuture.runAsync(() -> {
UserQueryRequest userQueryRequest = new UserQueryRequest();
userQueryRequest.setUserName(searchText);
userQueryRequest.setCurrent(current);
userQueryRequest.setPageSize(size);
Page<UserVO> userVOPage = userService.listUserVoByPage(userQueryRequest);
searchVo.setUserList(userVOPage.getRecords());
});
CompletableFuture<Void> postCF = CompletableFuture.runAsync(() -> {
PostQueryRequest postQueryRequest = new PostQueryRequest();
postQueryRequest.setSearchText(searchText);
postQueryRequest.setCurrent(current);
postQueryRequest.setPageSize(size);
Page<PostVO> postPage = postService.listPostVOByPage(postQueryRequest, request);
searchVo.setPostList(postPage.getRecords());
});
try {
CompletableFuture.allOf(postCF, userCF, picCF).get();
} catch (Exception e) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "查询数据异常");
}
} else {
DataSource dataSource = dataSourceRegistry.dataSourceMap.get(type);
List<?> list = dataSource.doSearch(searchText, current, size);
searchVo.setDataList(list);
}
return searchVo;
}
}
tips:
这里的真实有效的仅有dataList(其他三个是第二版的残留物)
/**
* @author:天才玩家M
* @date:2023/10/4 11:32
* @description:TODO
*/
@Data
public class SearchVo {
private List<Picture> picList;
private List<PostVO> postList;
private List<UserVO> userList;
private List<?> dataList;
}
适配器模式
为何使用?:
搜索中台中,我们之后可能会接入各种各样的type的搜索数据源,比如说我自己,有时候,几乎是同样功能的service只是数据源不一样,不复制粘贴就常常弄得各有各的接口,就很乱,所以出现了适配器模式,一方面,如果这个service不是我们写的,我们在其之后写,可以利用适配器尝试将对方改为我们的适配的api,或者我们先定了适配器,让对方按照我们的标准来实现
public interface DataSource<T> {
List<T> doSearch(String searchText,Long current,Long pageSize);
}
其他数据源:
public class PostDataSource implements DataSource<PostVO>{...}
注册器模式
为何使用?
承接上面的门面,以及适配器,在实际场景中我们肯定要根据不同的searchType更换,那么用switch?
太复杂了,那用一个map封装一下,之后get,差不多,这可大大节省了代码量
@Component
public class DataSourceRegistry {
public Map<String,DataSource> dataSourceMap=null;
@PostConstruct
public void initMap(){
dataSourceMap=new HashMap();
dataSourceMap.put(SearchTypeEnum.POST.getValue(),new PostDataSource());
dataSourceMap.put(SearchTypeEnum.PICTURE.getValue(),new PictureDataSource());
dataSourceMap.put(SearchTypeEnum.USER.getValue(),new UserDataSource());
}
}
ES的概念
倒排索引
正向索引:字典or通常书籍的目录
倒排索引:
输入数据时
会根据我们输入es的内容,先分词,然后统计哪个分词在哪个doc出现过,通过内容来检索到哪个doc
查找数据时
同样会通过分词,然后根据总共分词在哪些doc出现过,返回对应的数据
用户搜:“鱼皮rapper”
ES 先切词:鱼皮,rapper
去倒排索引表找对饮的文章:文章A,B
词 | 内容 id |
---|---|
你好 | 文章A,B |
我是 | 文章A,B |
rapper | 文章A |
鱼皮 | 文章B |
coder | 文章B |
一个待升级点
es会通过我们输入的searchText来分词然后返回docs,这些doc同时带有一定的评分,我们可以通过这些评分来倒序返回给用户,实现对应的功能
(类似:百度:查找的时候第一页的内容和我们搜索的相关性较高(抛开广告不谈的话),之后相关性逐渐降低)
待解决点:
page改成cur_point
能够优化ES性能
尤其是像我们手机电商这种页码不明显的情况下,当然明显也能替换
Sea-Search03总结&&un finish的更多相关文章
- sea.js模块化编程
* 为什么要模块化? 解决文件依赖 解决命名冲突 ; var var2 = 2; function fn1(){ } function fn2(){ } return { fn1: fn1, fn2: ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 在eclipse创建android project,最后一步点击finish没反应
在创建android project的时候,到最后一步点击finish没有反应. 本来以为可能是SDK中的Extra下Android Support Library没有安装,后来检查发现Minimum ...
- 解决sea.js引用jQuery提示$ is not a function的问题
在使用sea.js的如下写法引用jQuery文件时, //main.jsdefine(function(require,exports,module){ var $ = require('jquery ...
- Android中finish掉其它的Activity
在Android开发时,一般情况下我们如果需要关掉当前Activity非常容易,只需要一行代码 this.finish;即可.那么,如果是想要在当前Activity中关掉其它的Activity应该怎么 ...
- finish()在dialog中的作用
finish()在dialog中销毁的是dialog所在的活动:
- 模块化开发--sea.js
当你的网站开发越来越复杂的时候,会经常遇到一下问题吗?1.冲突2.性能3.依赖如果在多人开发或者是复杂的开发过程中会经常遇到这些问 题,就可以用模块化开发来解决.以上问题是如何产生的?1.冲突:如果你 ...
- sea.js 入门
上个月学了 require.js 现在顺便来学学 sea.js. 对比下这两种的区别,看自己喜欢哪个,就在接下来的项目中去使用它吧. seajs中的所有 JavaScript 模块都遵循 CMD 模块 ...
- 第三课:sea.js模块加载原理
模块加载,其实就是把js分成很多个模块,便于开发和维护.因此加载很多js模块的时候,需要动态的加载,以便提高用户体验. 在介绍模块加载库之前,先介绍一个方法. 动态加载js方法: function l ...
- Codeforces 738D. Sea Battle 模拟
D. Sea Battle time limit per test: 1 second memory limit per test :256 megabytes input: standard inp ...
随机推荐
- django动态创建表和动态选择实体
开发有时需要动态创建表,创建完成后需要动态选择model对应的表,该需求如何实现 1.model层 TestBlock为了动态创建表.getBlockModel为了动态选择表 from djang ...
- div模拟表格单元格合并
效果如下图: html代码如下: 1 <ul class="schedule-list"> 2 <li class="schedule-title&qu ...
- C#约瑟夫环问题算法
/// <summary> /// 约瑟夫环问题算法 /// </summary> /// <param name="total">总人数< ...
- docker 安装 ETCD 及 etcd 使用
本文为博主原创,未经允许不得转载: etcd 是 CoreOS 团队发起的一个开源项目(Go 语言,其实很多这类项目都是 Go 语言实现的,只能说很强大),实现了分布式键值存储和服务发现,etcd 和 ...
- Verilog仿真实践
Verilog必须掌握 逻辑仿真工具(VCS)和逻辑综合工具(DC) AndOR module AndOr( output X,Y, input A,B,C ); // A B进行按位与运算 assi ...
- GoMusic-歌单迁移工具网站 一键迁移网易云/QQ音乐歌单至 Apple/Youtube/Spotify Music
GoMusic是什么: GoMusic是一个在线歌单迁移工具网站,帮助用户一键迁移网易云/QQ音乐歌单至 Apple/Youtube/Spotify Music,直接输入歌单链接,复制查询结果,打开 ...
- 抓取java堆栈失败的思考-Safepoint等的学习
抓取java堆栈失败的思考-Safepoint等的学习 背景 前期解决问题都是靠抓取进程堆栈 jstack,后者是jmap到内存dump的方式来进行分析. 最近连续有两个比较大的项目出现了抓取dump ...
- [转帖]Spring为啥不推荐使用@Autowired注解?
https://my.oschina.net/u/5079097/blog/5289666 引言 使用IDEA开发时,同组小伙伴都喜欢用@Autowired注入,代码一片warning,看着很不舒 ...
- [转帖]火狐URL默认打开为HTTPS,切换成http形式
火狐在当前及未来版本默认URL采用HTTPS进行链接,但个人习惯,某些网站不是https,改http在响应超时状态也会切成https,将默认为http. edge,chrome 依然还是http为主要 ...
- 【转帖】读懂什么是RDMA
一.什么是RDMA1.RDMA主要体现 2.如何理解RDMA和TCP技术的区别?3.使用RDMA的好处包括: 二.什么是RoCE?1. RDMA协议包含:Infiniband(IB)2. 为什 ...