当前位置:   article > 正文

mongoTemplate支持多表联查 排序 条件筛选 分页 去重分组_mongotemplate多表查询

mongotemplate多表查询

在这里插入图片描述

说明

需求:
列表展示需要对mongo的两表进行连表查询,且根据两个不同的表中指定字段去排序分页展示,其中包含对两个表不同条件的筛选。

以下案例:
school主表和class次表,查询school里面为新民小学,并且名字叫高老师的所有班级,返回班级里面的所有学生的姓名、年龄。案例简单看看,主要看代码技术点。

代码

数据总条数

public long getTotal(String teacherName, String startTime, String endTime) {
        LookupOperation lookup = LookupOperation.newLookup()
        		//次表名称
                .from("class")
                //主表关联字段
                .localField("classId")
                //次表关联字段 
                .foreignField("classId")
                //临时表明 主要是给次表用
                .as("er");
                
		//数据类型转换,classId在一个表是string,另一个表是objectId类型,如果没有转换需求可忽略
        AddFieldsOperation addFieldsOperation = AddFieldsOperation
                .addField("classId")
                .withValue(ConvertOperators.ToObjectId.toObjectId("$classId")).build();

		//次表查询条件
        Criteria criteria = Criteria.where("er.teacher").is("高老师");
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            criteria.and("er.createTime").gte(dateToISODate(strToDateLong(startTime))).lte(dateToISODate(strToDateLong(endTime)));
        }

        Aggregation countAgg = Aggregation.newAggregation(
                //主表查询条件
                Aggregation.match(Criteria.where("schoolName").is("新民小学")),
                addFieldsOperation,
                lookup,
                //lookup以下是次表查询条件和分组
                Aggregation.unwind("er"),
                Aggregation.match(criteria),
                Aggregation.group("_id:null").count().as("count")
        );
        //school是主表名称
        AggregationResults<Map> resultCount = mongoTemplate.aggregate(countAgg, "school", Map.class);
        List<Map> countList = resultCount.getMappedResults();
        long count = 0L;
        if (countList.size() > 0) {
        // 拿到总条数,可以用于业务分页计算
            count = Long.parseLong(countList.get(0).get("count").toString());
        }
        return count;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

数据总体data

public List<ClassVo> infoData(String teacherName, String startTime, String endTime, Integer pageNum, Integer pageSize) {
        LookupOperation lookup = LookupOperation.newLookup()
        		//次表名称 班级
                .from("class")
                //主表关联字段
                .localField("classId")
                //次表关联字段 
                .foreignField("classId")
                //临时表明 主要是给次表用
                .as("er");

       //数据类型转换,classId在一个表是string,另一个表是objectId类型,如果没有转换需求可忽略
        AddFieldsOperation addFieldsOperation = AddFieldsOperation
                .addField("classId")
                .withValue(ConvertOperators.ToObjectId.toObjectId("$classId")).build();

		//次表查询条件
        Criteria criteria = Criteria.where("er.teacher").is(teacherName);
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            criteria.and("er.createTime").gte(dateToISODate(strToDateLong(startTime))).lte(dateToISODate(strToDateLong(endTime)));
        }

        Aggregation countAgg = Aggregation.newAggregation(
                Aggregation.match(Criteria.where("schoolName").is("新民小学")),
                addFieldsOperation,
                lookup,
                Aggregation.unwind("er"),
                Aggregation.match(criteria),
                //主表字段
                Aggregation.project("classId", "status")
                //次表字段都要用【er.】才能获取到
                        .andInclude("er._id", "er.tearcher", "er.student.name", "er.student.age"),
                //根据主表状态和次表年龄降序排序        
                Aggregation.sort(Sort.Direction.DESC, "status", "age"),
                //去重 连表查询避免不了一对多关系 会查出重复数据可以用group对id进行分组去重 .first可以理解为返回的字段as为返回的别名,这里可以理解为sql返回后的最终字段 如果要返回学生名称 不需要用er.student.name 直接name字段获取
                Aggregation.group("_id").first("_id").as("id")
                        .first("tearcher").as("tearcher")
                        .first("name").as("name")
                        .first("age").as("age"),
                //分页
                Aggregation.skip((pageNum - 1) * pageSize),
                Aggregation.limit(pageSize)
        );
        
        //school是主表名称
        AggregationResults<ServerRecordVo> resultCount = mongoTemplate.aggregate(countAgg, "school", ServerRecordVo.class);
        List<ServerRecordVo> vos = resultCount.getMappedResults();
        return vos;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

就先说到这 \color{#008B8B}{ 就先说到这} 就先说到这
在下 A p o l l o \color{#008B8B}{在下Apollo} 在下Apollo
一个爱分享 J a v a 、生活的小人物, \color{#008B8B}{一个爱分享Java、生活的小人物,} 一个爱分享Java、生活的小人物,
咱们来日方长,有缘江湖再见,告辞! \color{#008B8B}{咱们来日方长,有缘江湖再见,告辞!} 咱们来日方长,有缘江湖再见,告辞!

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/56033
推荐阅读
相关标签
  

闽ICP备14008679号