其他
最佳实践丨云数据库实现联表+聚合查询
聚合是云开发 CloudBase 数据库中非常重要的一种数据批处理操作方式。聚合操作可以将数据分组(或者不分组,即只有一组/每个记录都是一组),然后对每组数据执行多种批处理操作,最后返回结果。
有了聚合能力,可以方便的解决很多没有聚合能力时无法实现或只能低效实现的场景,包括分组查询、只取某些字段的统计值或变换值返回、流水线式分阶段批处理、获取唯一值(去重)等。
场景说明
假设数据库内存在两个集合:class
与 student
,存在以下数据:
class(班级信息)
代码示例
1、lookup 联表查询
lookup({
from: "student", //要关联的表student
localField: "id", //class表中的关联字段
foreignField: "class_id", //student表中关联字段
as: "stu" //定义输出数组的别名
}).end();
{"list":
[{
"id":1,
"teacher":"王老师",
"cname":"一班",
"stu":[
{
"sname":"宁一",
"class_id":1,
"score":90
}
]
},
{
"id":2,
"teacher":"徐老师",
"cname":"二班",
"stu":[
{
"class_id":2,
"sname":"张二",
"score":100
},
{
"class_id":2,
"sname":"李二",
"score":80
}
]
}]
}
但是我们只需要徐老师所在班级学生的数据,所以需要进一步过滤。
2、match 条件匹配
.lookup({
from: 'student',
localField: 'id',
foreignField: 'class_id',
as: 'stu'
})
.match({
teacher:"徐老师"
})
.end()
{
"list": [
{
"_id": "5e847ab25eb9428600a512352fa6c7c4",
"id": 2,
"teacher": "徐老师",
"cname": "二班",
//学生数据
"stu": [
{ "_id": "37e26adb5eb945a70084351e57f6d717", "class_id": 2, "sname": "张二", "score": 100 },
{ "_id": "5e847ab25eb945cf00a5884204297ed8", "class_id": 2, "sname": "李二", "score": 80 }
]
}
]
}
接下来我们继续优化代码,直接返回学生的平均分数。
3、直接返回学生成绩平均值
.lookup({
from: 'student',
pipeline: $.pipeline()
.group({
_id: null,
score: $.avg('$score')
})
.done(),
as: 'stu'
})
.match({
teacher:"徐老师"
})
.end()
{
"list": [
{
"_id": "5e847ab25eb9428600a512352fa6c7c4",
"id": 2,
"teacher": "徐老师",
"cname": "二班",
"stu": [{ "_id": null, "score": 90 }]
}
]
}
4、只显示 teacher 和 score 这两个值
我们使用 replaceRoot、mergeObjects 和 project 进行最后的处理:
.lookup({
from: 'student',
pipeline: $.pipeline()
.group({
_id: null,
score: $.avg('$score')
})
.done(),
as: 'stu'
})
.match({
teacher:"徐老师"
})
.replaceRoot({
newRoot: $.mergeObjects([$.arrayElemAt(['$stu', 0]), '$$ROOT'])
})
.project({
_id:0,
teacher:1,
score:1
})
.end()
现在输出的数据是这样的:
{ "list": [{ "score": 90, "teacher": "徐老师" }] }
还想看到哪些云开发的最佳实践?
欢迎在评论区留言~
点击在看让更多人发现精彩