评论

反电信网络诈骗普法宣传答题实现联表查询学生的平均成绩

反电信网络诈骗普法宣传答题实现联表查询学生的平均成绩。

国际经济与贸易学院组织反电信网络诈骗线上答题活动,开展集中普法宣传教育活动,从而构筑立体化反诈骗防线。

通过此次比赛,引导广大同学时刻牢记反诈骗内容,提高师生的自我财产安全防范意识,加强自我网络保护的思想理念,守护好大家的“钱袋子”。

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

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


使用lookup函数实现联表查询:

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

直接返回学生成绩平均值

如果想要在被连接的表格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这两个值,我们再进行下面的操作。

只显示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,就能控制最后输出的字段。


最后一次编辑于  2023-01-11  
点赞 0
收藏
评论
登录 后发表内容