MongoDB的行转列查询

项目组数据需求,需要将Mongo库中的列按日期分组转成行的格式进行显示。Mongo群里问了下,群里热心的大佬小徐 同学果断出手相助,顺利解决了数据问题。现将内容总结梳理如下,帮助有需要的其他同学

表结构

建表语句

db.class.insertMany( [
{ studentId: 1, class: "CLASS ONE", subject: "English", SCORE: 90 },
{ studentId: 1, class: "CLASS ONE", subject: "Math", SCORE: 100 },
{ studentId: 1, class: "CLASS ONE", subject: "PE", SCORE: 40 },
{ studentId: 2, class: "CLASS ONE", subject: "PE", SCORE: 80 },
{ studentId: 2, class: "CLASS ONE", subject: "English", SCORE: 95 },
{ studentId: 2, class: "CLASS ONE", subject: "Math", SCORE: 100 }
] )

表结构截图

在这里插入图片描述

期望数据展示

classstudentIdEnlishMathPE
CLASS ONE19010040
CLASS ONE29510080

查询语句

1. addFields方法

思路分为以下几步
(1)用addFields方法增加一个字段obj,用来存放学科和分数对象
在这里插入图片描述

(2)用学生ID进行分组,并将学生的所有的obj对象放到一个数组里
在这里插入图片描述
(3)将学生ID信息也以键值对的形式合并到数组中进行展现
在这里插入图片描述
(4)替换掉所有k,v形式,将上述的数组对象Item2以对象的形式展现
在这里插入图片描述
完整的查询语句如下所示

db.class.aggregate([
    { $addFields: { obj: { k: "$subject", v: "$SCORE" } } },
    { $group: { _id: "$studentId", item: { $push: "$obj" } } },
    {
        $project: {
            item2: {
                $concatArrays: [[{ k: "studentId", v: "$_id" }
                ], "$item"]
            }
        }
    },
    { $replaceWith: { $arrayToObject: "$item2" } }])

2. 不用addFields方法

思路同上
(1)分组将学科和分数以数组的形式放在一个字段item中
(2)将学生ID信息放到数组item中里,返回一个新的数组对象item2
(3) 将item2数组转对对象文档,将通过replaceWith将其k,v替换成字段和值的形式展现

db.class.aggregate([
    { $group: { _id: "$studentId", item: { $push: { k: "$subject", v: "$SCORE" } } } },
    { $project: { item2: { $concatArrays: [[{ k: "_id", v: "$_id" }], "$item"] } } },
    { $replaceWith: { $arrayToObject: "$item2" } }])

3

思路:
(1)用学生ID分组,将学科分值合并成一个数组并将其放到数组对象item中
在这里插入图片描述
(2) 将学生ID信息合并到item中,组成新的数组对象item2
在这里插入图片描述
(3)将数组对象item2以对象的形式展示,并通过replaceWith函数替换字段值的方式展示结果
在这里插入图片描述

db.class.aggregate([
    { $group: { _id: "$studentId", item: { $push: { "$concatArrays": [["$subject"], ["$SCORE"]] } } } }, 
    { $project: { item2: { $concatArrays: [[["_id", "$_id"]], "$item"] } } }, 
    { $replaceWith: { $arrayToObject: "$item2" } }
    ])

下面小尝试了下mapReduce

查询每个学生的总分

db.class.mapReduce(
    function() { emit(this.studentId, this.SCORE) } // map 函数
    , function(key, value) { return Array.sum(value) }, //reduce函数
    {
        out: "test.classTotalScore"
    })
db.test.classTotalScore.find()

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值