Erlo

项目中不一样的《建造者模式》

2024-12-17 18:29:26 发布   16 浏览  
页面报错/反馈
收藏 点赞

builder真的是为了创建复杂的对象而产生的,实际使用场景更侧重复杂对象的构建。
记录一下ES检索复杂对象场景的使用:
首先是抽象层的builder

点击查看代码
//构建查询where 条件
    interface BuildWhere {
        QueryBuilder build();
        public static void setDelWhere(final BoolQueryBuilder boolQueryBuilder){
            boolQueryBuilder.must(QueryBuilders.termQuery("isDel",0));
            boolQueryBuilder.must(QueryBuilders.termQuery("isImageExist",true));
        }
    }

再看builder实现

点击查看代码
    class SearchQueryBuilder{
        private SearchQueryVo searchQueryVo;
        private SearchRequest searchRequest;
        public SearchQueryBuilder(final SearchQueryVo searchQueryVo,final ElasticSearchIndexEnum indexEnum) {
            this.searchQueryVo = searchQueryVo;
            //指定查询的index
            searchRequest = new SearchRequest(indexEnum.getValue());
        }

        public String build(){
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            //查询条件 where
            BuildWhere strategy = strategy(searchQueryVo.getSearchTypeEnum());
            searchSourceBuilder.query(strategy.build());

            //分页limit
            searchSourceBuilder.from((searchQueryVo.getCurPage()-1)*searchQueryVo.getPageSize());
            searchSourceBuilder.size(searchQueryVo.getPageSize());

            /**
             * 排序
             * 如果是简单查询条件为空时,则按照inputTime desc
             * 其他则按照得分 desc
             * change:所有查询结果加入排序,时间排序
             */
            String order = searchQueryVo.getOrder();

            if (StringUtils.isNotBlank(order)) {
                if (order.equals(SortOrder.DESC.toString())) {
                    searchSourceBuilder.sort(new FieldSortBuilder("inputTime").order(SortOrder.DESC));
                }else if (order.equals(SortOrder.ASC.toString())){
                    searchSourceBuilder.sort(new FieldSortBuilder("inputTime").order(SortOrder.ASC));
                }
            }
            searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));

            //预处理prepare
            searchRequest.source(searchSourceBuilder);
            String searchString = searchService.getSearchString(searchRequest);
            log.debug("searchString :{}", searchString);
            return searchString;
        }

        /**
         * 自动选择查询类型
         * @param searchTypeEnum
         * @return
         */
        private BuildWhere strategy(SearchTypeEnum searchTypeEnum){
            BuildWhere buildWhere = null;
            switch (searchTypeEnum){
                case simple:
                    buildWhere = new SimpleBuild();
                    break;
                case height:
                    buildWhere=new HeightBuild();
                    break;
                case insearch:
                    buildWhere=new TwiceSearchBuild();
                    break;
                default:
                    log.error("not found search type of {}",searchTypeEnum);
            }
            return buildWhere;
        }

        /**
         * 默认创建第一次查询的条件
         * @return
         */
        private BoolQueryBuilder createBoolQueryBuilder(){
            return createBoolQueryBuilder(searchQueryVo.getOnceSearchVo());
        }

        /**
         * 构建一个boolQuery
         * @return
         */
        private BoolQueryBuilder createBoolQueryBuilder(SearchQueryVo.SearchVo searchVo){
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            if (searchVo == null) {
                return boolQueryBuilder;
            }
            //title(可能出现在多个字段中,这里为了防止可能出现其他字段,用multiMatch)
            String title = searchVo.getTitle();
            if (StringUtils.isNotBlank(title)) {
                boolQueryBuilder.must(QueryBuilders.multiMatchQuery(title,"headline").analyzer("ik_smart"));
            }

            //图片元素标签
            List elementLabel = searchVo.getElementLabel();
            if (CollectionUtils.isNotEmpty(elementLabel)) {
                //图片元素标签在量字段中查询
                BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
                boolQuery.should((QueryBuilders.termsQuery("imageScenes.name",elementLabel)));
                boolQuery.should((QueryBuilders.termsQuery("imageItems.name",elementLabel)));
                boolQueryBuilder.filter(boolQuery);
            }

            //图片来源
            List imageSource = searchVo.getImageSource();
            if (CollectionUtils.isNotEmpty(imageSource)) {
                boolQueryBuilder.filter(QueryBuilders.termsQuery("imageSource",imageSource));
            }
            //作者
            List newsGrapherName = searchVo.getNewsGrapherName();
            if (CollectionUtils.isNotEmpty(newsGrapherName)) {
                boolQueryBuilder.filter(QueryBuilders.termsQuery("newsGrapherName",newsGrapherName));
            }
            //关键词
            String keywords = searchVo.getKeywords();
            if (StringUtils.isNotBlank(keywords)) {
                boolQueryBuilder.must(QueryBuilders.multiMatchQuery(keywords,"caption","headline","searchKey").analyzer("ik_smart"));
            }
            //开始时间
            String imageTimeStart = searchVo.getImageTimeStart();
            if (StringUtils.isNotBlank(imageTimeStart)) {
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("imageTime").gte(imageTimeStart));
            }
            //结束时间
            String imageTimeEnd = searchVo.getImageTimeEnd();
            if (StringUtils.isNotBlank(imageTimeEnd)) {
                boolQueryBuilder.filter(QueryBuilders.rangeQuery("imageTime").lte(imageTimeEnd));
            }

            return boolQueryBuilder;
        }


        /**
         * 简单检索
         */
        private class SimpleBuild implements BuildWhere {

            /**
             * 如果简单查询没有任何条件限制,则返回列表按照时间DESC
             * @return
             */
            public QueryBuilder build() {
                BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
                String titleOrKeywordOrTag = searchQueryVo.getTitleOrKeywordOrTag();
                if (StringUtils.isNotBlank(titleOrKeywordOrTag)) {
                    MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(searchQueryVo.getTitleOrKeywordOrTag(), filedNames).analyzer("ik_smart");
                    boolQueryBuilder.must(multiMatchQueryBuilder);
                }
                BuildWhere.setDelWhere(boolQueryBuilder);
                return boolQueryBuilder;
            }

        }

        /**
         * 高级检索
         */
        private class HeightBuild implements BuildWhere {
            public QueryBuilder build() {
                BoolQueryBuilder boolQueryBuilder = createBoolQueryBuilder();
                BuildWhere.setDelWhere(boolQueryBuilder);
                return boolQueryBuilder;
            }
        }

        /**
         * 结果中检索
         */
        private class TwiceSearchBuild implements BuildWhere {

            public QueryBuilder build() {
                //构建第一次查询(最外层条件)
                BoolQueryBuilder outBoolQueryBuilder = createBoolQueryBuilder();

                //结果中二次筛选查询(第二层条件)
                BoolQueryBuilder in1BoolQueryBuilder = createBoolQueryBuilder(searchQueryVo.getTwiceSearchVo());

                //将二层条件噻到最外层条件去(这里只能使用boolQuery,才能实现在filter使用match/multi-match 这种全文匹配)
                outBoolQueryBuilder.filter(in1BoolQueryBuilder);

                BuildWhere.setDelWhere(outBoolQueryBuilder);
                return outBoolQueryBuilder;
            }

        }



    }

构建复杂对象,还得是builder.build()。

实际项目中无形中就用到了这些模式,也不用刻意去硬套模式。
在即将结束的职业生涯余光里,没事记录一下自己的代码风格。

本文来自博客园,作者:Eular,转载请注明原文链接:https://www.cnblogs.com/euler-blog/p/18611179

登录查看全部

参与评论

评论留言

还没有评论留言,赶紧来抢楼吧~~

手机查看

返回顶部

给这篇文章打个标签吧~

棒极了 糟糕透顶 好文章 PHP JAVA JS 小程序 Python SEO MySql 确认