赞
踩
关于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();
接下来根据代码分析:
首先是主表条件,就是对最后mongoTemplate.aggregation(aggregation,Org.class).getMappedResults()中Org.Class对应的表直接进行操作,这一步的结果大致如下:
[
{
"orgId":"",
"orgName":"",
"createTime":""
},
....
]
Lookup进行联表操作
LookupOperation lookup = LookupOperation.newLookup()
.from("task") //次表
.localField("orgId") //主表关联字段
.foreignField("orgId") //次表关联字段
.as("link"); //临时集合别名
这一步是把次表中满足关联条件(关联字段相等,类似于sql的inner join)的数据查出来作为一个数组,用as指定的别名嵌入到上一步的操作中,此时的结果大致如下:
[ { "orgId":"", "orgName":"", "createTime":"", "link":[ { "taskId":"", "orgId":"", "title":"", "createTime":"" }, ... ] }, .... ]
次表条件,是将步奏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"))), //创建时间倒序,在下一步分组中取出排序后的首位
此时的结果集:
[ { "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
再在此基础上进行分组:
...
//分组操作,取首位数据,并指定需要字段的别名(分组字段的值会默认放在"_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")
最后的结果集大致如下:
[
{
"orgId":"o1",
"title":"tt1",
"createTime":"time4"
},
{
"orgId":"o2",
"title":"tt2",
"createTime":"time2"
},
]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。