Table of contents
1. Description
Recently, the project received a function point, which required sorting the status value field according to rules. This status stores pure String letters in the table, and the sorting requirements cannot be based on the dictionary sorting method. How to solve this problem?
MongoDB currently only supports ascending or descending order of certain fields . However, in some special scenarios, such as Chinese, it is required to sort according to specified rules. In this case, MongoDB's custom sorting rules are used.
2. Code case implementation
Customize queries through collections
Criteria criteria = new Criteria();
criteria.and("sid").is(000000L);
criteria.and("file_type").in(Arrays.asList("PPTX", "DOCX"));
List<AggregationOperation> operations = new ArrayList<>();
Fields fields = Fields.fields("id","create_time","update_time","status");
// 添加查询条件
operations.add(Aggregation.match(criteria));
if("desc".equals(order)){
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("notStarted")).then("1").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("going")).then("2").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("success")).then("3").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("fail")).then("4").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields).and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("error")).then("5").otherwiseValueOf("status")));
operations.add(Aggregation.sort(Sort.by(Sort.Direction.DESC, "update_time","status")));
}else{
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("notStarted")).then("5").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("going")).then("4").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("success")).then("3").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("fail")).then("2").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("error")).then("1").otherwiseValueOf("status")));
operations.add(Aggregation.sort(Sort.by(Sort.Direction.ASC, "update_time","status")));
}
// 设置分页参数
operations.add(Aggregation.skip((page-1)*size));
operations.add(Aggregation.limit(size));
// 根据上面自定义的排序规则将对应的数据转换回来
if("desc".equals(order)){
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("1")).then("notStarted").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("2")).then("going").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("3")).then("success").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("astatus").applyCondition(ConditionalOperators.when(Criteria.where("status").is("4")).then("fail").otherwiseValueOf("status")));
operations.add(Aggregation.project(fields)
.and("status").applyCondition(ConditionalOperators.when(Criteria.where("status").is("5")).then("error").otherwiseValueOf("status")));
}else{
//todo 类似
}
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<JSONObject> aggregationResults = mongoTemplate.aggregate(aggregation, "test_record", JSONObject.class);
List<JSONObject> templateList = aggregationResults.getMappedResults();