mongodb之使用聚合方法条件排序查询
温馨提示:这篇文章已超过385天没有更新,请注意相关的内容是否还可用!
目录
(图片来源网络,侵删)
一、springboot使用聚合方法处理业务查询排序心得
- 思路
- 提的问题
二、分页代码
三、对二中condSortParam参数进行加工后的程序
- AggregationOperation加工方法
- 入口调用方法
五、总结
一、springboot使用聚合方法处理业务查询排序心得
- 思路。此文编程部分思路大部分通过文心一言(免费版本即可) 获取。
注意:但在首次使用所给的答案绕了远路,第二回通过给他发送明确的内容做基础,如发送 mongosh脚本后 给出了编码 才拿到正确的解答方式
注意:在springboot中使用正确的方式编程,springboot中使用aggregate方法与使用mongosh 脚本基本方法名称相同, 不然会出现问题(奇怪的问题)
- 如下是提的问题。询问文心一言内容
- 注意首先编写mongosh脚本进行查询。查询结果正确后。询问文心一言获取springboot的编程代码
如:
db.document.aggregate([{ $addFields: { sortOrder: { $cond: { if: { $eq: ["$status", "8"] }, then: 1, else: { $cond:{ if: { $eq: ["$status", "9"] },then: 2, else: -1 } } } } } }, { $sort: { sortOrder: -1, applyTime: -1 } },{ $project: { _id: 1, accNum: 1, status: 1, applyTime: 1 } } ]);将上述脚本 用springboot 编程实现二、分页代码
-
注意:此代码为分页方法,传入的CondSortParam是经过加工后传入的,带有mongo聚合查询需要的AggregationOperation与SortOperation
-
注意:Aggregation.newAggregation中 AggregationOperation参数的排列顺序会影像查询结果
例如:
排序1查询结果会先排序后通过条件进行处理。
SortOpertion, AddFieldsOpertion.....
解决方法:倒置:AddFieldsOpertion, SortOpertion...
/* * 分页公共方法 */ public static PageVO pagination(PageRequestDTO dto, Class tClass, MongoTemplate mongoTemplate, CondSortParam condSortParam) { # 获取查询条件 Criteria criteria = handleCriteria(dto); // 添加查询条件 MatchOperation matchOperation = Aggregation.match(criteria); // 计算总数, 分页 Query query = new Query(); query.addCriteria(criteria); if (!ObjectUtils.allNotNull(dto.getCurrentPageNum())) { dto.setCurrentPageNum(0); } if (!ObjectUtils.allNotNull(dto.getSize())) { dto.setSize(10); } long count = mongoTemplate.count(query, tClass); log.info("统计sql: {}", query); int offset = (dto.getCurrentPageNum() - 1) * dto.getSize(); # 分页条件处理 SkipOperation skipOperation = Aggregation.skip(offset); LimitOperation limitOperation = Aggregation.limit(dto.getSize()); Aggregation aggregation = null; List list = new ArrayList(); if(condSortParam != null) { list.add(matchOperation); # 此处为【添加字段】条件集合 condSortParam.getAddFieldsOperations().forEach(s-> list.add(s)); if(condSortParam.getSortOperation() != null) { list.add(condSortParam.getSortOperation()); } list.add(skipOperation); list.add(limitOperation); aggregation = Aggregation.newAggregation(list); } log.info("分页查询sql: {}", aggregation); List results = mongoTemplate.aggregate(aggregation, tClass, tClass).getMappedResults(); PageVO pageVO = new PageVO(); pageVO.setTotalNum(count); pageVO.setResults(results); return pageVO; } /* * 处理查询条件 */ private static Criteria handleCriteria(PageRequestDTO dto) { List params = dto.getParams(); Criteria criteria = new Criteria(); if(CollUtil.isEmpty(params)) return criteria; params.forEach(param -> { String operator = param.getOperator(); switch (operator) { case "eq" -> criteria.and(param.getField()).is(param.getFieldValue()); case "like" -> criteria.and(param.getField()).regex(Pattern.compile("^.*" + param.getFieldValue() + ".*$", Pattern.CASE_INSENSITIVE)); case "le" -> criteria.and(param.getField()).lt(param.getFieldValue()); case "ge" -> criteria.and(param.getField()).gt(param.getFieldValue()); case "in" -> { List values = null; if (param.getFieldValue() instanceof JSONArray) { JSON.parseArray(param.getFieldValue().toString(), String.class); criteria.and(param.getField()).in(values); }else if(param.getFieldValue() instanceof String){ criteria.and(param.getField()).in(param.getFieldValue().toString().split(StrUtil.COMMA)); } } case "between" -> { if (param.getFieldValue() instanceof JSONArray) { List list = JSON.parseArray(param.getFieldValue().toString(), Object.class); if (CollUtil.isNotEmpty(list)) { criteria.and(param.getField()).gte(list.get(0)).lte(list.get(1)); } } } default -> { } } }); return criteria; }三、对二中condSortParam参数进行加工后的程序
- AggregationOperation加工方法
注意:此处使用switch应对业务场景创建,不同case的处理operation的复杂度不同
较复杂case:添加了两个字段的判断 代码case上已标注
简单case:只添加了一个字段的判断 代码case上已标注
/* * 获取聚合函数所需参数 */ public static DataToolUtil.CondSortParam createDCondSortParamByPageType(String pageType) { String [] codes; String addSortFieldName = "statusOrder"; String sortFieldName = "status"; AtomicInteger level = new AtomicInteger(); SortOperation sortOperation; switch (pageType) { # 简单case case D_STATUS.TYPE_APPLY: codes = new String[]{D_STATUS.APPLY_REJECT.getCode(), D_STATUS.AUDITED_PRINTED.getCode(), D_STATUS.AUDITED.getCode() , D_STATUS.APPLY.getCode(), D_STATUS.APPLY_REVOKE.getCode(), D_STATUS.SUBMIT.getCode() , D_STATUS.REPORT_REJECT.getCode(), D_STATUS.REVOKE_AUDITED.getCode(), D_STATUS.REVOKE.getCode() , D_STATUS.REPORT_DRAFT.getCode(), D_STATUS.DATA_DESTRY.getCode() }; sortOperation = Aggregation.sort(Sort.Direction.DESC, addSortFieldName, "applyTime"); return new DataToolUtil.CondSortParam.Builder() .addFieldOperation(createCondSortParamByPageType(sortFieldName, codes, level, addSortFieldName)) .addSortOperation(sortOperation) .build(); # 简单case case D_STATUS.TYPE_REPORT: codes = new String[]{D_STATUS.REPORT_REJECT.getCode(), D_STATUS.REVOKE.getCode(), D_STATUS.REPORT_DRAFT.getCode() , D_STATUS.APPLY.getCode(), D_STATUS.APPLY_REJECT.getCode() }; sortOperation = Aggregation.sort(Sort.Direction.DESC, addSortFieldName, "applyTime"); return new DataToolUtil.CondSortParam.Builder() .addFieldOperation(createCondSortParamByPageType(sortFieldName, codes, level, addSortFieldName)) .addSortOperation(sortOperation) .build(); # 复杂case, 添加了两个AddSortFieldName case D_STATUS.TYPE_AUDIT: DataToolUtil.RelationWrapper statusWrapper = DataToolUtil.RelationWrapper.builder() .addSortFieldName(addSortFieldName).sortFieldname(sortFieldName).build(); DataToolUtil.RelationWrapper pati..Wrapper = DataToolUtil.RelationWrapper.builder() .addSortFieldName("pati....ypeIdOrder").sortFieldname("pati....ypeId").build(); codes = new String[]{D_STATUS.REVOKE.getCode(), D_STATUS.SUBMIT.getCode(), D_STATUS.AUDITED.getCode(), D_STATUS.AUDITED_PRINTED.getCode()}; sortOperation = Aggregation.sort(Sort.Direction.DESC, pati..Wrapper.getAddSortFieldName()).and(Sort.by(Sort.Direction.DESC, statusWrapper.getAddSortFieldName(), "app...ime")); return new DataToolUtil.CondSortParam.Builder() .addFieldOperation(createCondSortParamByPageType(statusWrapper.getSortFieldname(), codes, level, statusWrapper.getAddSortFieldName())) .addFieldOperation(createCondSortParamByPageType(pati..Wrapper.getSortFieldname(), new String[]{PATIENT_TYPE.EMERGENCY.getCode()}, level, pati..Wrapper.getAddSortFieldName())) .addSortOperation(sortOperation) .build(); default: return null; } } /** * 分页排序公共参数。 * 带条件排序字段与排序字段的排列顺序 */ @Data @Builder public static class CondSortParam{ /** 提供的AggregationOperation */ List addFieldsOperations; /** 组合排序字段。如 Aggregation.sort(Direction.DESC, "sortOrder", "applyTime") */ SortOperation sortOperation; public static class Builder { private CondSortParam condSortParam = CondSortParam.builder().build(); public Builder() { this.condSortParam.addFieldsOperations = new ArrayList(); } public Builder addFieldOperation(AddFieldsOperation addFieldsOperation) { this.condSortParam.addFieldsOperations.add(addFieldsOperation); return this; } public Builder addSortOperation(SortOperation sortOperation) { this.condSortParam.sortOperation = sortOperation; return this; } public CondSortParam build() { return this.condSortParam; } } } /* * 绑定排序时需要条件判断而添加的字段名称与原字段名称 */ @Data @lombok.Builder public static class RelationWrapper { /** 增加的字段,拍寻优先级使用 */ private String addSortFieldName; /** 需要被排序的字段, 条件判断使用 */ private String sortFieldname; }- 入口调用方法
@Operation(summary = "列表查询", parameters = { @Parameter(name = "pageRequest", description = "...", required = true) }) @PostMapping("queryPage") public CommonJsonResponseVO queryPage(@RequestBody PageRequestDTO pageRequest) { ... PageVO pageVO = DataToolUtil.pagination(pageRequest, RemoteDiagnosis.class, mongoTemplate, Status.createDiagCondSortParamByPageType(pageRequest.getPageType())); return CommonJsonResponseVO.success(PageUtil.toPage(pageVO.getResults(), pageVO.getTotalNum())); }总结
- 复杂排序的完成需要从简单的排序入手。逐渐增加复杂度将有路可循。
- AI的正确使用会提高成功效率。只是凭借以往的查询方式(如百度查询等)无法深入挖掘一个工具的使用方法,比较困难。
- 对象化的参数会对复杂的排序提高可读性、易用性。如:RelationWrapper 对参数进行抽象
- 入口调用方法
- AggregationOperation加工方法
-
- 思路。此文编程部分思路大部分通过文心一言(免费版本即可) 获取。
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!
