项目组数据需求,需要将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 }
] )
表结构截图

期望数据展示
| class | studentId | Enlish | Math | PE | 
|---|---|---|---|---|
| CLASS ONE | 1 | 90 | 100 | 40 | 
| CLASS ONE | 2 | 95 | 100 | 80 | 
查询语句
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()




















