当前位置:   article > 正文

MongoTemplate联表查询_mongotemplate join

mongotemplate join

关于mongoTemplate的联表查询,之前的内容没有描述清楚,这次清空了重写。

案例关系:org通过 orgId一对多 关联task,需要查出每个org和其最新的一个task

org ——orgId——> task1、task2、…

代码:

            LookupOperation lookup = LookupOperation.newLookup()
                    .from("task") //次表
                    .localField("orgId") //主表关联字段
                    .foreignField("orgId") //次表关联字段
                    .as("link"); //临时集合别名

            Aggregation aggregation = Aggregation.newAggregation(
                    //主表条件
                    Aggregation.match(Criteria.where("isDel").ne(1)),
                    //联表
                    lookup,
                    //次表条件 
                    Aggregation.unwind("link"),
                	Aggregation.match(Criteria.where("link.isDel").ne(1)),
                    Aggregation.sort(Sort.by(Sort.Order.desc("link.createTime"))),
                    Aggregation.group("task.orgId")
                           	.first("link.title").as("title")
                            .first("orgId").as("orgId")
                            .first("orgName").as("orgName")
                            .first("link.createTime").as("createTime"), 
                    Aggregation.sort(Sort.by(Sort.Order.desc("createTime"),Sort.Order.desc("orgId"))),
                    Aggregation.project("orgId","title","createTime")
            );

            List<Org> orgs = mongoTemplate.aggregation(aggregation,Org.class).getMappedResults();
  • 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

接下来根据代码分析:

  1. 首先是主表条件,就是对最后mongoTemplate.aggregation(aggregation,Org.class).getMappedResults()Org.Class对应的表直接进行操作,这一步的结果大致如下:

    [
        {
            "orgId":"",
            "orgName":"",
            "createTime":""
        },
        ....
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  2. Lookup进行联表操作

                LookupOperation lookup = LookupOperation.newLookup()
                        .from("task") //次表
                        .localField("orgId") //主表关联字段
                        .foreignField("orgId") //次表关联字段
                        .as("link"); //临时集合别名
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这一步是把次表中满足关联条件(关联字段相等,类似于sql的inner join)的数据查出来作为一个数组,用as指定的别名嵌入到上一步的操作中,此时的结果大致如下:

    [
        {
            "orgId":"",
            "orgName":"",
            "createTime":"",
            "link":[
                {
                    "taskId":"",
                    "orgId":"",
                    "title":"",
                    "createTime":""
                },
                ...
            ]
        },
        ....
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  3. 次表条件,是将步奏2的结果进行操作。由于联表的结果是个内嵌的数组,如果需要的是一对一的关系,需要进行Aggregation.unwind()再进行操作。例如此处要取出每个org最新的一个task:

    					//次表条件,对步奏2的结果集进行操作
                        Aggregation.unwind("link"), //拆分link
                    	Aggregation.match(Criteria.where("link.isDel").ne(1)), //过滤条件
                        Aggregation.sort(Sort.by(Sort.Order.desc("link.createTime"))), //创建时间倒序,在下一步分组中取出排序后的首位 
    
    • 1
    • 2
    • 3
    • 4

    此时的结果集:

    [
        {
            "orgId":"o1",
            "orgName":"",
            "createTime":"",
            "link":{
                "taskId":"t1",
                "orgId":"o1",
                "title":"tt1",
                "createTime":"time4"
            }
        },
        {
            "orgId":"o1",
            "orgName":"",
            "createTime":"",
            "link":{
                "taskId":"t2",
                "orgId":"o1",
                "title":"tt2",
                "createTime":"time3"
            }
        },
        {
            "orgId":"o2",
            "orgName":"",
            "createTime":"",
            "link":{
                "taskId":"t3",
                "orgId":"o2",
                "title":"tt3",
                "createTime":"time2"
            }
        },
        {
            "orgId":"o2",
            "orgName":"",
            "createTime":"",
            "link":{
                "taskId":"t4",
                "orgId":"o2",
                "title":"tt4",
                "createTime":"time1"
            }
        },
        ....
    ]
    //其中,time1<time2<time3<time4
    
    • 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

    再在此基础上进行分组:

                        ...
                        //分组操作,取首位数据,并指定需要字段的别名(分组字段的值会默认放在"_id"上)
    					Aggregation.group("task.orgId") 
                            	.first("link.title").as("title")
                                .first("orgId").as("orgId")
                                .first("orgName").as("orgName")
                                .first("link.createTime").as("createTime"), 
                        Aggregation.project("orgId","title","createTime")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    最后的结果集大致如下:

    [
        {
            "orgId":"o1",
            "title":"tt1",
            "createTime":"time4"
        },
        {
            "orgId":"o2",
            "title":"tt2",
            "createTime":"time2"
        },
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

总结

  1. 在LookupOperation前的操作,针对主表操作
  2. LookupOperation,指定关联doc,关联字段,和联表结果集别名。并将结果集以数组形式嵌入到**<1>**的对应结果中。
    此时整个结果集只会剩下存在关联关系的数据(inner join
  3. 在LookupOperation后的操作,针对<2>的结果集进行操作
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/56038
推荐阅读
相关标签
  

闽ICP备14008679号