云开发如何建立测试数据库微信开放社区,简单几步,就能在云开发数据库实现联表数据查询!

在前面的文章中,我们介绍了如何用“库存”看懂云开发数据库事务,讲述了在云开发数据库重构中如何将字段抽离成单独的集合;今天我们来学习云开发联表数据的查询,并教大家如何在云函数中应用,在微信开发者工具中打印出我们查询的结果。

先来设定一下场景,现在有两个表格,我们来查询一下徐老师所带的班级里面所有学生的平均成绩:

1、联表查询

先看一下如何查询,将这两个表连起来的数据是class表中的id和student表中的class_id.

所以我们应该先查出徐老师所在班级的id,是2,然后再查询student表中class_id为2的学生,张二和李二,计算这两个学生的平均成绩。

来看一下在云开发中如何实现这样一个联表查询。云开发文档中,在开发指引--数据库中,就有联表查询的介绍,我们使用lookup函数实现联表查询:

lookup({from: ,localField: ,foreignField: ,as: })(1) lookup联接两个表格

应用到我们上面设定的场景,就像下面这样写,需要调用 end 方法来标志结束定义:

lookup({from: 'student',//要关联的表studentlocalField: '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}]}]}

但是我们只需要徐老师所在班级学生的数据,所以需要加一个where条件,在lookup后面不能直接跟where,而是match来代替,下面我们来改进上面的代码。

(2) 使用match进行条件查询.lookup({from: 'student',localField: 'id',foreignField: 'class_id',as: 'stu'}).match({teacher:"徐老师"}).end()

现在就只是返回徐老师所在班级的学生数据了,学生数据在stu对应的数组里面:

{"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) 直接返回学生成绩平均值

如果想要在被连接的表格中(本课程中的student)做聚合操作,就用pipeline方法。

但是pipeline不能与localField、foreignField共用,所以我们先删掉localField、foreignField再在pipeline中取得学生成绩(score)的平均值:

.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}]}]}

但是现在输出的数据有点复杂,如果只想显示teacher和score这两个值,我们再进行下面的操作。

(4) 只显示teacher和score这两个值.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":"徐老师"}]}

replaceRoot({ newRoot:})是固定写法,将已有字段作为一个新节点输出,我们通常用他来将二级数组变成一级数组。

mergeObjects是累计器操作符,$.arrayElemAt(['$stu', 0]), '$$ROOT’]就是将stu数组中的第一个元素,也就是[{"_id":null,"score":90}]合并到数组的跟节点上面,也就是与teacher、cname这些字段同一级。

project里面将_id后面设为0,将我们想要显示的元素后面设为1,就能控制最后输出的字段。

2、在云函数中的应用

接下来看看怎样在云函数中运用吧,在微信开发者工具中打印出我们上面查询的结果。

(1) 在云数据库中添加数据

我们在微信开发者工具中打开云开发控制台,先在云数据库中创建这两个表,我们以创建class表为例。

创建好表格后,我们再在表格中添加记录,根据我们上面表格中的数据来添加,下面添加的是二班的数据。

数据都添加好了之后,来到微信开发者工具云函数文件夹下面创建一个名为test的云函数云开发的这个项目我们是提前创建好了,如果不知道怎样创建的,可以看之前我发的30分钟创建创建并上线云开发小程序的课程,里面有教大家如何创建。

(2) 创建云函数并初始化数据库

创建完成后,系统会帮咱们创建一个test文件夹,我们打开test/index.js文件,将部分默认创建的代码删掉,并初始化数据库,像下面这样:

// 云函数入口文件const cloud = require('wx-server-sdk')cloud.init()//初始化数据库const db = cloud.database()const _ = db.commandconst $ = _.aggregate// 云函数入口函数exports.main = async (event, context) => {//下面继续在这里面添加代码}(3) 编辑云函数入口函数// 云函数入口函数exports.main = async (event, context) => {return await db.collection('class').aggregate().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()}

编辑完成之后保存文件,并上传部署云函数。

(4) 上传部署云函数

右键点击云函数,选择上传并部署:云端安装依赖(不上传node_modules)

打开云开发控制台—点击云函数--找到test云函数点击云端测试:

在弹出的测试框中,直接点击运行测试按钮

下面就会打印出返回的结果,说明现在已经联表查询成功了!

本文分享自微信公众号 - 腾讯云云开发(tcb2tcb),作者:猫宁一

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

024日军登陆0406200000的HS编码031竹马将军06有效溝通的方法2021年高考英语全国乙卷真题参考答案微信转账照片微信转账照片3000元0852最新章节全文阅读0852蟹总全文阅读蟹总补肉烈途截图0144软硬钉子接连碰047甜蜜与危机03不敌美国队但女排的状态正在回归052我喜欢听你叫贺太太唐李白杨叛儿约战精灵再临小米服id查询我靠玄学翻红了我靠卖玉雕火遍娱乐圈026战神将军050暴走皇帝vs第一宠妃50喝奶茶对身体有什么坏处电视原理习题答案第二章vivoy66配置参数形势与政策中国崛起论文1500字