前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单几步,就能在云开发数据库实现联表数据查询!

简单几步,就能在云开发数据库实现联表数据查询!

作者头像
腾讯云开发TCB
发布2020-06-17 17:42:44
3.7K0
发布2020-06-17 17:42:44
举报
文章被收录于专栏:云开发云开发云开发

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

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

1、联表查询

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

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

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

lookup({
  from: <要连接的集合名>,
  localField: <输入记录的要进行相等匹配的字段>,
  foreignField: <被连接集合的要进行相等匹配的字段>,
  as: <输出的数组字段名>
})
(1) lookup联接两个表格

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

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

但是我们只需要徐老师所在班级学生的数据,所以需要加一个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不能与localFieldforeignField共用,所以我们先删掉localFieldforeignField再在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
        }
      ]
    }
  ]
}

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

(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.command
const $ = _.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云函数点击云端测试:

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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云开发CloudBase 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、联表查询
    • (1) lookup联接两个表格
      • (2) 使用match进行条件查询
        • (3) 直接返回学生成绩平均值
          • (4) 只显示teacher和score这两个值
          • 2、在云函数中的应用
            • (1) 在云数据库中添加数据
              • (2) 创建云函数并初始化数据库
                • (3) 编辑云函数入口函数
                  • (4) 上传部署云函数
                  相关产品与服务
                  云函数
                  云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性、安全地运行代码。云函数是实时文件处理和数据处理等场景下理想的计算平台。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档