首页 > 其他分享 >Sea-Search03总结&&un finish

Sea-Search03总结&&un finish

时间:2023-10-23 20:55:08浏览次数:40  
标签:finish SearchVo private Search03 searchQueryRequest CompletableFuture Sea new pu

使用到的设计模式

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性能

尤其是像我们手机电商这种页码不明显的情况下,当然明显也能替换

标签:finish,SearchVo,private,Search03,searchQueryRequest,CompletableFuture,Sea,new,pu
From: https://www.cnblogs.com/seamount3/p/17783453.html

相关文章

  • 【解决】elasticsearch:Could not parse aggregation keyed as [%s]问题
    背景在做elasticsearch集群从原来的2.x版本升级到更新版本如6.x过程中,由于需要在原来的应用中,同时连接2.x的集群以及6.x的集群来做在线动态灰度切流量,保证流量平滑切换,有问题可随时回切;一般在应用侧比较常规的做法是使用elasticsearch提供rest的sdk:JavaHighLevelRESTClient,......
  • Elasticsearch_exporter + Prometheus + Grafana监控之搭建梳理
    一、安装elasticsearch_exporter并启动1.1官网下载elasticsearch_exporter的安装包,地址如下:如果是Linux系统,建议安装此版本:elasticsearch_exporter-1.3.0.linux-amd64.tar.gzhttps://github.com/prometheus-community/elasticsearch_exporter/releases1.2上传安装包到服务......
  • 商超外卖搜索基于Elasticsearch的优化实践
    业务背景我们是外卖搜索系统,在传统的外卖的基础上,推出了便利超市的功能。但是与外卖商家不同的是,我们有很多大型的商超,每个商超的商品数量会非常多,导致线上调用ES大量超时且ES负载较重。由于我们是多国家业务当前是根据国家拆分所以,以情况最为严重的泰国为例,有数万家商家,和几千......
  • ElasticSearch 拼音分词和自动补全
    在搜索过程中,大部分情况下会有智能提示功能,也就是开头匹配的自动补全功能,这就需要用到ElasticSearch的Suggest查询功能。用户也可能输入拼音或者查询关键字的首字母简写,比如我想查询华为手机,我可以输入hwsj进行查询,这就需要用到拼音分词器。本篇博客将介绍如何安装拼音分词......
  • search
    "search":"/components/search/search"//components/search/search.jsComponent({properties:{innerText:{type:String,value:'搜索',}},data:{},methods:{redirect(){wx.navigateTo......
  • Elasticsearch的架构
    1.3Elasticsearch的架构Gateway层es用来存储索引文件的一个文件系统且它支持很多类型,例如:本地磁盘、共享存储(做snapshot的时候需要用到)、hadoop的hdfs分布式存储、亚马逊的S3。它的主要职责是用来对数据进行长持久化以及整个集群重启之后可以通过gateway重新恢复数据。Distributed......
  • SpringCloudAlibaba Seata在Openfeign跨节点环境出现全局事务Xid失效原因底层探究
    原创/朱季谦曾经在SpringCloudAlibaba的Seata分布式事务搭建过程中,跨节点通过openfeign调用不同服务时,发现全局事务XID在当前节点也就是TM处,是正常能通过RootContext.getXID()获取到分布式全局事务XID的,但在下游节点就出现获取为NULL的情况,导致全局事务失效,出现异常时无法正常回......
  • INFINI Labs 产品更新 | Easysearch 优化字段压缩提升写入速度,Console 优化数据迁移和
    INFINILabs产品又更新啦~。本次更新概要如下:Easysearch增强source_reuse压缩功能,并大幅提升写入速度;Console优化了数据迁移和校验功能,新增了通用的数据列表和下拉等标准组件,化繁为简,实现可复用。以下是本次更新的详细说明。INFINIEasysearchv1.6.1INFINIEasysearch是......
  • 使用docker命令行为elasticsearch安装ik中文分词插件
    背景:mac+dockerdesktop+elasticsearch7.8.0 一、安装ik中文分词插件dockerexec-itelastic_search/bin/bash-c'bin/elasticsearch-plugininstallhttps://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.8.0/elasticsearch-analysis-ik-7.8.0......
  • elasticsearch 设置高亮
    1、引入配置springboot环境<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version></parent>引入es配置<!--e......