es 报表聚合,分组,求和,排序,合计,分页等综合应用_es 求和-程序员宅基地

 一,最终实现:查询条件及查询结果如下图所示
需要实现:分组,求和,聚合后排序,总计,分页

二, 需求分析:关于分组维度
es数据主键为:日期(年月日)+采购组织+采购组+门店

统计维度:可根据是否选择门店,按日或按月统计可分为四种情况

日+采购组织+采购组;采购组织+采购组;日+采购组织+采购组+门店;月+采购组织+采购组+门店;

按正常es多条件分组求和处理方式很麻烦,可参考网上写法。可以转变思路,把每个维度拼接成一个字段,即新增四个字段,多条件分组统计转化为单条件分组统计,实现起来会简单的多。如下图所示:

 三,代码实现
关于聚合

难点在于聚合统计,及聚合统计后再合计

关于排序

聚合求和的字段排序与不需要聚合求和的字段区分开来,前者可以直接应用es特性直接排序,后者排序,对处理之后的数据lis排序,java特性排序对list排序

关于分页

es无法复杂聚合后排序,对处理之后的数据进行伪分页排序,并不是真正意义上的排序,可以减轻前端压力,对于后台是对所有的数据伪分页。

serviceImpl
 

  public Page<ResFoodOrderInspectionVO> queryPageByOrgGroupLocationCodes(ReqFoodOrderInspectionVO reqVO) {
        // 参数处理
        paramDeal(reqVO);
        Page<ResFoodOrderInspectionVO> page = new Page<>();
        page.setPageSize(reqVO.getSize());
        page.setPageNo(reqVO.getPage());
        page.setOrderBy(reqVO.getOrderBy());
 
        // 聚合查询
        List<ResFoodOrderInspectionVO> resList = esService.queryGroupByOrgGroupLocationCode(reqVO);
        if (CollectionUtils.isEmpty(resList)) {
            return new Page<>();
        }
        
        // 百分率处理
        percentDeal(resList);
        
        // 非聚合字段排序处理
        orderBy(resList, reqVO);
 
        page.setTotalNum(resList.size());
        page.setResult(pageHandle(resList, reqVO.getPage(), reqVO.getSize()));
        return page;
    }

es逻辑

  @Override
    public List<ResFoodOrderInspectionVO> queryGroupByOrgGroupLocationCode(ReqFoodOrderInspectionVO reqVO) {
        log.info("食用订单巡检表查询条件:{}", reqVO.toString());
        StopWatch stopwatch = new StopWatch();
        stopwatch.start();
        List<ResFoodOrderInspectionVO> resList = Lists.newArrayList();
        SearchRequest searchRequest = new SearchRequest(EsOperateTables.FOOD_ORDER_INSPECTION.getAlias());
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.fetchSource(RES_FBASEFOODORDERINSPEC_FIELDS, null);
        searchSourceBuilder.size(0);// 设置为0代表不需要取查询到的所有数据,只需要取聚合的相关的数据
        BoolQueryBuilder booleanQuery = QueryBuilders.boolQuery();
        // 组装查询条件
        buildBooleanQuery(booleanQuery, reqVO);
        searchSourceBuilder.query(QueryBuilders.constantScoreQuery(booleanQuery));
        // 分组,统计,排序
        FoodOrderInspectionConvertor.groupCountAgg(searchSourceBuilder, reqVO);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            stopwatch.stop();
        } catch (IOException e) {
            log.error(ErrorMsgConstant.FOODORDERINSPECTION_QUERYES_ERROR, e);
            throw new OrderCenterException(ErrorMsgConstant.FOODORDERINSPECTION_QUERYES_ERROR);
        }
        if (Objects.isNull(searchResponse)) {
            return Collections.emptyList();
        }
 
        Terms terms = searchResponse.getAggregations().get(FoodOrderInspectionConstant.GROUPDIMENSION);
        if (Objects.isNull(terms)) {
            return Collections.emptyList();
        }
        // 包含门店,且按日统计时,需要判断总量,其他场景,总分组量实际不会大于10000,不需要判断
        if (CollectionUtils.isNotEmpty(reqVO.getLocationCodes()) && !reqVO.getGroupMonth() && searchResponse.getHits().getTotalHits() > FoodOrderInspectionConstant.GROUP_RETURN_SIZE) {
            throw new OrderCenterException(ErrorMsgConstant.GROUP_TOTALSIZE_TOOLONG);
        }
        // 组装数据
        for (Terms.Bucket entry : terms.getBuckets()) {
            resList.add(FoodOrderInspectionConvertor.toResVO(entry, reqVO));
        }
        // 取聚合统计后合计
        Map<String, Aggregation> totalMap = searchResponse.getAggregations().getAsMap();
        resList.forEach(v -> {
            v.setResFoodOrderInspectionTotalVO(FoodOrderInspectionConvertor.buildTotal(totalMap));
        });
        log.info("食用订单巡检报表查询耗时:{}", stopwatch.getTotalTimeMillis());
        return resList;
    }

 聚合求和及聚合合计字段处理

1.注意维度下数据量,如果大于10000条,多余的数据不会计入聚合统计,如下图说明

2.注意聚合求和和聚合合计的层级关系,聚合统计字段以子聚合关联,聚合合计字段与分组维度一个层级

 /**
     * 统计,排序
     * 分组size含义:需要返回分组后的个数;如按某维度分组,10个结果,size=2,只会返回两个结果。应该小于10000
     * 分组size测试:
     * 条件:全部100家门店,日期5月份,包含门店,按日维度统计
     * 结果:查询总量:19703 1,size>10000,程序异常;2,size=10000(查询时长大概30s),实际只取前10000条数据聚合返回,导致数据不准
     * 处理:如果size>10000,抛业务异常,缩小范围
     *
     * @param searchSourceBuilder
     * @param reqVO
     */
    public static void groupCountAgg(SearchSourceBuilder searchSourceBuilder, ReqFoodOrderInspectionVO reqVO) {
        //对聚合结果的排序 true为正序 false为倒序
        Boolean sort = FoodOrderInspectionConstant.ASC.equals(reqVO.getSort()) ? true : false;
 
        //聚合场景
        TermsAggregationBuilder groupDimension = null;
        if (CollectionUtils.isNotEmpty(reqVO.getLocationCodes()) && reqVO.getGroupMonth()) {
            groupDimension = AggregationBuilders.terms(FoodOrderInspectionConstant.GROUPDIMENSION).field(convertToUnderScore(BaseFoodOrderInspectionVO::getMonthOrgGroupLocation)).size(FoodOrderInspectionConstant.GROUP_RETURN_SIZE);
        } else if (CollectionUtils.isEmpty(reqVO.getLocationCodes()) && !reqVO.getGroupMonth()) {
            groupDimension = AggregationBuilders.terms(FoodOrderInspectionConstant.GROUPDIMENSION).field(convertToUnderScore(BaseFoodOrderInspectionVO::getDayOrgGroup)).size(FoodOrderInspectionConstant.GROUP_RETURN_SIZE);
        } else if (CollectionUtils.isEmpty(reqVO.getLocationCodes()) && reqVO.getGroupMonth()) {
            groupDimension = AggregationBuilders.terms(FoodOrderInspectionConstant.GROUPDIMENSION).field(convertToUnderScore(BaseFoodOrderInspectionVO::getMonthOrgGroup)).size(FoodOrderInspectionConstant.GROUP_RETURN_SIZE);
        } else if (CollectionUtils.isNotEmpty(reqVO.getLocationCodes()) && !reqVO.getGroupMonth()) {
            groupDimension = AggregationBuilders.terms(FoodOrderInspectionConstant.GROUPDIMENSION).field(FoodOrderInspectionConstant._ID).size(FoodOrderInspectionConstant.GROUP_RETURN_SIZE);
        } else {
            return;
        }
 
        // 判断是否在聚合排序范围
        List<String> fileds = Arrays.stream(ReqFoodOrderInspectionOderByVO.class.getDeclaredFields()).map(field -> field.getName()).collect(Collectors.toList());
        if (fileds.contains(reqVO.getOrderBy())) {
            groupDimension.order(BucketOrder.aggregation(reqVO.getOrderBy(), sort));
        }
 
        // 分组维度内取第一个元素
        TopHitsAggregationBuilder topHits = null;
        if (CollectionUtils.isNotEmpty(reqVO.getLocationCodes()) && !reqVO.getGroupMonth()) {
            topHits = AggregationBuilders.topHits(FoodOrderInspectionConstant.TOP_HITS_ONE).size(1).fetchSource(RES_FBASEFOODORDERINSPEC_FIELDS, null);
        } else {
            topHits = AggregationBuilders.topHits(FoodOrderInspectionConstant.TOP_HITS_ONE).size(1).fetchSource(ORG_GROUP_LOCATION_FIELDS, null);
        }
 
        //聚合统计
        SumAggregationBuilder replenishAdviceQtySum = AggregationBuilders.sum(FoodOrderInspectionConstant.REPLENISHADVICEQTY).field(convertToUnderScore(BaseFoodOrderInspectionVO::getReplenishAdviceQty));
        SumAggregationBuilder actApproveProductNumSum = AggregationBuilders.sum(FoodOrderInspectionConstant.ACTAPPROVEPRODUCTNUM).field(convertToUnderScore(BaseFoodOrderInspectionVO::getActApproveProductNum));
        SumAggregationBuilder actApproveQtySum = AggregationBuilders.sum(FoodOrderInspectionConstant.ACTAPPROVEQTY).field(convertToUnderScore(BaseFoodOrderInspectionVO::getActApproveQty));
        SumAggregationBuilder actReplenishProductNumSum = AggregationBuilders.sum(FoodOrderInspectionConstant.ACTREPLENISHPRODUCTNUM).field(convertToUnderScore(BaseFoodOrderInspectionVO::getActReplenishProductNum));
        SumAggregationBuilder actReplenishAdviceQtySum = AggregationBuilders.sum(FoodOrderInspectionConstant.ACTREPLENISHADVICEQTY).field(convertToUnderScore(BaseFoodOrderInspectionVO::getActReplenishAdviceQty));
        SumAggregationBuilder addProductNumSum = AggregationBuilders.sum(FoodOrderInspectionConstant.ADDPRODUCTNUM).field(convertToUnderScore(BaseFoodOrderInspectionVO::getAddProductNum));
        SumAggregationBuilder manualReplenishProductNumSum = AggregationBuilders.sum(FoodOrderInspectionConstant.MANUALREPLENISHPRODUCTNUM).field(convertToUnderScore(BaseFoodOrderInspectionVO::getManualReplenishProductNum));
        SumAggregationBuilder aiReplenishProductNumSum = AggregationBuilders.sum(FoodOrderInspectionConstant.AIREPLENISHPRODUCTNUM).field(convertToUnderScore(BaseFoodOrderInspectionVO::getAiReplenishProductNum));
        SumAggregationBuilder specialReplenishProductNumDqSum = AggregationBuilders.sum(FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMDQ).field(convertToUnderScore(BaseFoodOrderInspectionVO::getSpecialReplenishProductNumDq));
        SumAggregationBuilder specialReplenishProductNumTgSum = AggregationBuilders.sum(FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMTG).field(convertToUnderScore(BaseFoodOrderInspectionVO::getSpecialReplenishProductNumTg));
        SumAggregationBuilder specialReplenishProductNumYcSum = AggregationBuilders.sum(FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMYC).field(convertToUnderScore(BaseFoodOrderInspectionVO::getSpecialReplenishProductNumYc));
        SumAggregationBuilder orderProductNumSum = AggregationBuilders.sum(FoodOrderInspectionConstant.ORDERPRODUCTNUM).field(convertToUnderScore(BaseFoodOrderInspectionVO::getOrderProductNum));
        SumAggregationBuilder orderQtySum = AggregationBuilders.sum(FoodOrderInspectionConstant.ORDERQTY).field(convertToUnderScore(BaseFoodOrderInspectionVO::getOrderQty));
        SumAggregationBuilder adviceReplenishProductNumSum = AggregationBuilders.sum(FoodOrderInspectionConstant.ADVICEREPLENISHPRODUCTNUM).field(convertToUnderScore(BaseFoodOrderInspectionVO::getAdviceReplenishProductNum));
 
        // 聚合统计后再合计
        SumBucketPipelineAggregationBuilder replenishAdviceQtySumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.REPLENISHADVICEQTYTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.REPLENISHADVICEQTY);
        SumBucketPipelineAggregationBuilder approveProductNumSumBucketAct = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.ACTAPPROVEPRODUCTNUMTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.ACTAPPROVEPRODUCTNUM);
        SumBucketPipelineAggregationBuilder actApproveQtySumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.ACTAPPROVEQTYTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.ACTAPPROVEQTY);
        SumBucketPipelineAggregationBuilder actReplenishProductNumSumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.ACTREPLENISHPRODUCTNUMTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.ACTREPLENISHPRODUCTNUM);
        SumBucketPipelineAggregationBuilder actReplenishAdviceQtySumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.ACTREPLENISHADVICEQTYTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.ACTREPLENISHADVICEQTY);
        SumBucketPipelineAggregationBuilder addProductNumSumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.ADDPRODUCTNUMTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.ADDPRODUCTNUM);
        SumBucketPipelineAggregationBuilder manualReplenishProductNumSumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.MANUALREPLENISHPRODUCTNUMTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.MANUALREPLENISHPRODUCTNUM);
        SumBucketPipelineAggregationBuilder aiReplenishProductNumSumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.AIREPLENISHPRODUCTNUMTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.AIREPLENISHPRODUCTNUM);
        SumBucketPipelineAggregationBuilder specialReplenishProductNumDqSumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMDQTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMDQ);
        SumBucketPipelineAggregationBuilder specialReplenishProductNumTgSumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMTGTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMTG);
        SumBucketPipelineAggregationBuilder specialReplenishProductNumYcSumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMYCTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMYC);
        SumBucketPipelineAggregationBuilder orderProductNumSumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.ORDERPRODUCTNUMTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.ORDERPRODUCTNUM);
        SumBucketPipelineAggregationBuilder orderQtySumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.ORDERQTYTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.ORDERQTY);
        SumBucketPipelineAggregationBuilder adviceReplenishProductNumSumBucket = new SumBucketPipelineAggregationBuilder(FoodOrderInspectionConstant.ADVICEREPLENISHPRODUCTNUMTOTAL, FoodOrderInspectionConstant.GROUPDIMENSION + FoodOrderInspectionConstant.GROUPFLAG + FoodOrderInspectionConstant.ADVICEREPLENISHPRODUCTNUM);
 
        searchSourceBuilder.aggregation(groupDimension.subAggregation(topHits).subAggregation(replenishAdviceQtySum).subAggregation(actApproveProductNumSum)
                .subAggregation(actApproveQtySum).subAggregation(actReplenishProductNumSum).subAggregation(actReplenishAdviceQtySum).subAggregation(addProductNumSum)
                .subAggregation(manualReplenishProductNumSum).subAggregation(aiReplenishProductNumSum).subAggregation(specialReplenishProductNumDqSum).subAggregation(specialReplenishProductNumTgSum)
                .subAggregation(specialReplenishProductNumYcSum).subAggregation(orderProductNumSum).subAggregation(orderQtySum).subAggregation(adviceReplenishProductNumSum));
 
        // 添加合计聚合结果,与分组同一维度,不能加在上面subAggregation()中
        searchSourceBuilder.aggregation(replenishAdviceQtySumBucket).aggregation(approveProductNumSumBucketAct).aggregation(actApproveQtySumBucket).aggregation(actReplenishProductNumSumBucket)
                .aggregation(actReplenishAdviceQtySumBucket).aggregation(addProductNumSumBucket).aggregation(manualReplenishProductNumSumBucket).aggregation(aiReplenishProductNumSumBucket).aggregation(specialReplenishProductNumDqSumBucket)
                .aggregation(specialReplenishProductNumTgSumBucket).aggregation(specialReplenishProductNumYcSumBucket).aggregation(orderProductNumSumBucket).aggregation(orderQtySumBucket).aggregation(adviceReplenishProductNumSumBucket);
    }

 取聚合统计后合计数据

  /**
     * 取聚合统计后合计,返回double
     *
     * @param totalMap
     * @return
     */
    public static ResFoodOrderInspectionTotalVO buildTotal(Map<String, Aggregation> totalMap) {
        ResFoodOrderInspectionTotalVO vo = new ResFoodOrderInspectionTotalVO();
        vo.setReplenishAdviceQtyTotal(new BigDecimal(String.valueOf(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.REPLENISHADVICEQTYTOTAL)).value())).setScale(2, BigDecimal.ROUND_DOWN));
        vo.setActApproveProductNumTotal(Integer.valueOf(new Double(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.ACTAPPROVEPRODUCTNUMTOTAL)).value()).intValue()));
        vo.setActApproveQtyTotal(new BigDecimal(String.valueOf(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.ACTAPPROVEQTYTOTAL)).value())).setScale(2, BigDecimal.ROUND_DOWN));
        vo.setActReplenishProductNumTotal(Integer.valueOf(new Double(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.ACTREPLENISHPRODUCTNUMTOTAL)).value()).intValue()));
        vo.setActReplenishAdviceQtyTotal(new BigDecimal(String.valueOf(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.ACTREPLENISHADVICEQTYTOTAL)).value())).setScale(2, BigDecimal.ROUND_DOWN));
        vo.setAddProductNumTotal(Integer.valueOf(new Double(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.ADDPRODUCTNUMTOTAL)).value()).intValue()));
        vo.setManualReplenishProductNumTotal(Integer.valueOf(new Double(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.MANUALREPLENISHPRODUCTNUMTOTAL)).value()).intValue()));
        vo.setAiReplenishProductNumTotal(Integer.valueOf(new Double(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.AIREPLENISHPRODUCTNUMTOTAL)).value()).intValue()));
        vo.setSpecialReplenishProductNumDqTotal(Integer.valueOf(new Double(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMDQTOTAL)).value()).intValue()));
        vo.setSpecialReplenishProductNumTgTotal(Integer.valueOf(new Double(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMTGTOTAL)).value()).intValue()));
        vo.setSpecialReplenishProductNumYcTotal(Integer.valueOf(new Double(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.SPECIALREPLENISHPRODUCTNUMYCTOTAL)).value()).intValue()));
        vo.setOrderProductNumTotal(Integer.valueOf(new Double(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.ORDERPRODUCTNUMTOTAL)).value()).intValue()));
        vo.setOrderQtyTotal(new BigDecimal(String.valueOf(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.ORDERQTYTOTAL)).value())).setScale(2, BigDecimal.ROUND_DOWN));
        vo.setAdviceReplenishProductNumTotal(Integer.valueOf(new Double(((ParsedSimpleValue) totalMap.get(FoodOrderInspectionConstant.ADVICEREPLENISHPRODUCTNUMTOTAL)).value()).intValue()));
        return vo;
    }

非聚合字段排序

  /**
     * 非聚合字段排序
     *
     * @param resList
     * @param reqVO
     */
    public void orderBy(List<ResFoodOrderInspectionVO> resList, ReqFoodOrderInspectionVO reqVO) {
        if (!Stream.of(APPLYDATE_ORG_GROUP_LOCATION_FIELDS).collect(Collectors.toList()).contains(reqVO.getOrderBy())) {
            return;
        }
        if (FoodOrderInspectionConstant.APPLYDATE.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getApplyDate));// 升序
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getApplyDate).reversed());//降序
            }
        }
        if (FoodOrderInspectionConstant.PURCHASEGROUPCODE.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getPurchaseGroupCode));
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getPurchaseGroupCode).reversed());
            }
        }
        if (FoodOrderInspectionConstant.PURCHASEORGCODE.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getPurchaseOrgCode));
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getPurchaseOrgCode).reversed());
            }
        }
        if (CollectionUtils.isNotEmpty(reqVO.getLocationCodes()) && FoodOrderInspectionConstant.LOCATIONCODE.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getLocationCode));
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getLocationCode).reversed());
            }
        }
 
        // 百分比排序
        if (FoodOrderInspectionConstant.REPLENISHACCEPTPERCENT.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getReplenishAcceptPercent));
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getReplenishAcceptPercent).reversed());
            }
        }
        if (FoodOrderInspectionConstant.ADDREPLENISHPERCENT.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getAddReplenishPercent));
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getAddReplenishPercent).reversed());
            }
        }
        if (FoodOrderInspectionConstant.MANUALREPLENISHPERCENT.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getManualReplenishPercent));
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getManualReplenishPercent).reversed());
            }
        }
        if (FoodOrderInspectionConstant.AIREPLENISHPERCENT.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getAiReplenishPercent));
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getAiReplenishPercent).reversed());
            }
        }
        if (FoodOrderInspectionConstant.SPECIALREPLENISHPERCENT.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getSpecialReplenishPercent));
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getSpecialReplenishPercent).reversed());
            }
        }
        if (FoodOrderInspectionConstant.QTYUPDATEPERCENT.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getQtyUpdatePercent));
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getQtyUpdatePercent).reversed());
            }
        }
        if (FoodOrderInspectionConstant.PRODUCTUPDATEPERCENT.equals(reqVO.getOrderBy())) {
            if (FoodOrderInspectionConstant.ASC.equals(reqVO.getSort())) {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getProductUpdatePercent));
            } else {
                resList.sort(Comparator.comparing(ResFoodOrderInspectionVO::getProductUpdatePercent).reversed());
            }
        }
    }

 伪分页

  /**
     * 伪分页实现
     *
     * @param list
     * @param pageNum
     * @param pageSize
     * @param <T>
     * @return
     */
    public <T> List<T> pageHandle(List<T> list, int pageNum, int pageSize) {
        int fromIndex = (pageNum - 1) * pageSize;
        int toIndex = pageNum * pageSize;
        int maxIndex = list.size();
        fromIndex = fromIndex >= 0 ? fromIndex : 0;
        toIndex = toIndex <= maxIndex ? toIndex : maxIndex;
        if (fromIndex > toIndex) {
            fromIndex = 1;
        }
        return list.subList(fromIndex, toIndex);
    }

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/WXF_Sir/article/details/115611829

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf