mongodb去重分页查询支持排序

需求:
查询一张表,根据某字段去重后返回指定信息,支持分页,排序。

逻辑:
1,match查询符合条件的数据
2,利用分组进行去重
3,返回全部字段信息
4,排序
5,分页

mongodb原生语句实现
方法1 返回指定字段

db.getCollection('表名').aggregate([
{
    "$match" : {"failure":{$in:["具体失效文件"]}}    //查询数组类型字段,根据需求可更改
},
{  
     "$group" : {
         "_id": { "lawId": "$lawId" },     //需要去重的字段
         "id":{"$first" :"$_id"},              
         "lawId": {"$first" :"$lawId"},
         "date":{"$first" :"$date"}
         }
},
{
    "$project": {               //设置返回字段,建立在group基础上
       "_id": 1,
         "id":1,
         "lawId": 1,
         "date":1
    }
},
{"$sort": {"date":-1}},            //排序
{ "$skip":0 }, { "$limit":10 }     //分页
])

 

方法2 返回全部字段

db.getCollection('表名').aggregate([
{
    "$match" : {"failure":{$in:["具体失效文件"]}}      //查询数组类型字段,根据需求可更改
},
{  
     "$group" : {
         "_id": { "lawId": "$lawId" },     //需要去重的字段
         "data":{"$first" :"$$ROOT"}      //返回全部字段
         }
},
{
    "$project": {
      "data":1,                         //返回全部字段
    }
},
{"$sort": {"data.dae":-1}},             //根据date.dae字段排序
{ "$skip":0 }, { "$limit":10 }          //分页
])

java代码MongoTemplate实现方法2

/**
     * 处理group时使用流式操作,务必注意顺序
     * params 查询条件
     * page  分页信息
     * sortKey 排序值
     * direction 升序还是降序
     * filedsNameList 自定义返回的字段
     * groupKey 需要去重的字段
     */
    protected Aggregation getGeneralAggregation(Map<String, Object> params,
                                                Page<T> page,
                                                String sortKey,
                                                Direction direction,
                                                List<String> filedsNameList,
                                                String groupKey) {
        List<AggregationOperation> aggOptions = new ArrayList<>();
        { // 添加查询条件
            List<Criteria> criteriaList = new ArrayList<>();
            if (params != null) {
                logger.debug("查询参数:" + params);
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    if (entry.getKey() != null && entry.getValue() != null) {
                        switch (entry.getValue().getClass().getName()) {
                        case "java.util.ArrayList":
                        case "java.util.LinkedList":
                            criteriaList.add(Criteria.where(entry.getKey()).in(entry.getValue()));
                            break;
                        default:
                            criteriaList.add(Criteria.where(entry.getKey()).is(entry.getValue()));
                            break;
                        }
                    }
                }
            }
            aggOptions.add(Aggregation.match(new Criteria().andOperator(criteriaList.toArray(new Criteria[criteriaList.size()]))));
        }
        { // 分组
            if (StringUtils.isNotEmpty(groupKey)) {
                aggOptions.add(new GroupOperation(Aggregation.fields(groupKey)).first("$$ROOT")
                                                                               .as("data"));
            }
        }
        { // 排序
            sortKey = "data." + (sortKey == null ? "id" : sortKey);
            List<Order> orders = new ArrayList<Order>();
            orders.add(new Order(direction, sortKey));
            Sort sort = Sort.by(orders);
            aggOptions.add(Aggregation.sort(sort));
        }
        { // 分页
            if (page != null) {
                aggOptions.add(Aggregation.skip((long) (page.getPageNumber() > 0
                        ? (page.getPageNumber() - 1) * page.getPageSize()
                        : 0)));
                aggOptions.add(Aggregation.limit(page.getPageSize()));
            }
        }
        { // 添加返回field
            if (CollectionUtils.isNotEmpty(filedsNameList)) {
                filedsNameList = filedsNameList.stream()
                                               .map(str -> "data." + str)
                                               .collect(Collectors.toList());
                aggOptions.add(Aggregation.project(filedsNameList.toArray(new String[filedsNameList.size()])));
            }
        }
        Aggregation aggregation = Aggregation.newAggregation(aggOptions);
        return aggregation;
    }

  

然后调用

//agg是上面代码返回的Aggregation
 AggregationResults<T> list getMongoTemplate().aggregate(agg, getClassT(),getClassT());
list.getMappedResults();  //获取结果


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值