MongoDB自定义排序规则
MongoDB暂时只支持按照某些字段的升序或者降序排列, 在某些场景下, 可能会使用到MongoDB的自定义排序规则, 比如对中文有要求按照指定规则排序, 此时需要用到自定义排序, 解决方案如下:
注: 使用本方法只能采用聚合查询
@Test
public void sortTest() {
List<AggregationOperation> operations = new ArrayList<>();
Fields fields = Fields.fields("id", "name", "parentEnterprise", "parentEnterpriseId", "organizationId", "organizationName", "enterpriseType", "violationType");
// 添加查询条件
operations.add(Aggregation.match(Criteria.where("gmtCreat").gte(new Date()).lte(new Date())));
// 构建排序规则, 将对应的中文替换为便于排序的数据, 比如数字和字母
operations.add(Aggregation.project(fields)
.and("violationType").applyCondition(ConditionalOperators.when(Criteria.where("violationType").is("离线位移")).then("1").otherwiseValueOf("violationType")));
operations.add(Aggregation.project(fields)
.and("violationType").applyCondition(ConditionalOperators.when(Criteria.where("violationType").is("超速")).then("2").otherwiseValueOf("violationType")));
operations.add(Aggregation.project(fields)
.and("violationType").applyCondition(ConditionalOperators.when(Criteria.where("violationType").is("疲劳驾驶")).then("3").otherwiseValueOf("violationType")));
// 确定排序规则
operations.add(Aggregation.sort(Sort.by(Sort.Direction.DESC, "violationType")));
// 设置分页参数
operations.add(Aggregation.skip(1L));
operations.add(Aggregation.limit(10));
// 根据上面自定义的排序规则将对应的数据转换回来
operations.add(Aggregation.project(fields)
.and("violationType").applyCondition(ConditionalOperators.when(Criteria.where("violationType").is("1")).then("离线位移").otherwiseValueOf("violationType")));
operations.add(Aggregation.project(fields)
.and("violationType").applyCondition(ConditionalOperators.when(Criteria.where("violationType").is("2")).then("超速").otherwiseValueOf("violationType")));
operations.add(Aggregation.project(fields)
.and("violationType").applyCondition(ConditionalOperators.when(Criteria.where("violationType").is("3")).then("疲劳驾驶").otherwiseValueOf("violationType")));
// 聚合查询
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<DemoPO> results = mongoTemplate.aggregate(aggregation, "collection_name", DemoPO.class);
}