背景
因业务需求,MongoDB 按照多字段排序。以下代码亲自验证过,现分享给有需要的同学。
实现代码
@Data
public class AppCateModuleQo implements Serializable {
private final static Long serialVersionUID = 1L;
/**
* Pagination Start
*/
private Integer start;
/**
* Pagination Size
*/
private Integer size;
/**
* Orders
* Map.of("release_time", -1, "order", 1);
*/
private List<Map<String, Integer>> orders;
/**
* Condition
*/
private Object condition;
}
/**
* Get List By Qo
*
* @param qo AppCateModuleQo
* @return AppArticlePo
*/
public List<AppCateModulePo> getListByQo(AppCateModuleQo qo) {
Criteria criteria = new Criteria();
if (StrUtil.isNotBlank(qo.getId())) {
criteria.and("_id").is(qo.getId());
}
MatchOperation matchOperation = Aggregation.match(criteria);
ProjectionOperation projectionOperation = Aggregation.project("*");
LimitOperation limitOperation = Aggregation.limit(qo.getSize());
List<Sort.Order> sortList = this.buildSortDsl(qo.getOrders());
List<AggregationOperation> aggregationOperationList = new ArrayList<>();
aggregationOperationList.add(matchOperation);
if (CollectionUtil.isNotEmpty(sortList)) {
AggregationOperation sort = Aggregation.sort(Sort.by(sortList));
aggregationOperationList.add(sort);
}
aggregationOperationList.add(limitOperation);
aggregationOperationList.add(projectionOperation);
Aggregation aggregation = Aggregation.newAggregation(
aggregationOperationList
);
List<AppCateModulePo> appCateModulePo = this.mongoTemplate.aggregate(aggregation, AppConstant.MONGO_COLL_NAME_CATE_MODULE, AppCateModulePo.class).getMappedResults();
return appCateModulePo;
}
/**
* Build Sort Dsl
*
* @param sortList List<Map<String, Integer>>
* @return List<Sort.Order>
*/
private List<Sort.Order> buildSortDsl(List<Map<String, Integer>> sortList) {
if (CollectionUtil.isEmpty(sortList)) {
return new ArrayList<>();
}
List<Sort.Order> sortDslList = new ArrayList<>();
for (Map<String, Integer> sortItem : sortList) {
for (String sortKey : sortItem.keySet()) {
if (sortItem.get(sortKey) >= 1) {
Sort.Order order = new Sort.Order(Sort.Direction.ASC, sortKey);
sortDslList.add(order);
}
if (sortItem.get(sortKey) <= 0) {
Sort.Order order = new Sort.Order(Sort.Direction.DESC, sortKey);
sortDslList.add(order);
}
}
}
return sortDslList;
}
MongoDB DSL
[{ "$match" : {}}, { "$sort" : { "order" : 1, "release_time" : -1}}, { "$limit" : 2}, { "$project" : { "*" : 1}}]