MongoDB 聚合管道中使用数组表达式运算符实现数组元素映射($map)与统计(reduce)

数组表达式运算符主要用于文档中数组的操作,本篇我们主要介绍数组元素的映射及统计:

一、准备工作

初始化学生的学科成绩

db.subjects.insertMany([
    { "_id": 1, "name": "张三", "subjects": [ 
        { "name": "英语", "score": 80 }, { "name": "数学", "score": 70 } ] },
    { "_id": 2, "name": "李四", "subjects": [ 
        { "name": "英语", "score": 60 }, { "name": "数学", "score": 90 } ] },
    { "_id": 3, "name": "王五", "subjects": [ 
        { "name": "英语", "score": 90 }, { "name": "数学", "score": 50 } ] }
])

二、数组元素映射($map)

语法:

{ 
    $map: { 
        input: <expression>, 
        as: <string>, 
        in: <expression> 
    } 
}

在数组的每个元素上执行表达式,并将所有的执行结果组成新数组返回。

其中,

        input: 代表的是输入的数组

        as:可选,代表的是指向数组中元素的变量,如果没有定义,变量名默认是this

        in:数组中元素需要执行的表达式

例子:计算学生的学科成绩是否及格

db.subjects.aggregate([{
    $project: {
        "name": 1,
        "subjects": {
            $map: {
                input: "$subjects",
                as: "subject",
                in: {
                   $mergeObjects: [ "$$subject",  {
                        "level": {
                            $cond: {
                               if: { $gte: [ "$$subject.score", 60 ] }, 
                               then: "及格",
                               else: "不及格"
                            }
                        }
                   }]
                }
            }
        }
    }
}])

等效于:

db.subjects.aggregate([{
    $project: {
        "name": 1,
        "subjects": {
            $map: {
                input: "$subjects",
                in: {
                   $mergeObjects: [ "$$this",  {
                        "level": {
                            $cond: {
                               if: { $gte: [ "$$this.score", 60 ] }, 
                               then: "及格",
                               else: "不及格"
                            }
                        }
                   }]
                }
            }
        }
    }
}])

聚合查询的结果如下:

{ "_id" : 1, "name" : "张三", "subjects" : [ { "name" : "英语", "score" : 80, "level" : "及格" }, { "name" : "数学", "score" : 70, "level" : "及格" } ] }
{ "_id" : 2, "name" : "李四", "subjects" : [ { "name" : "英语", "score" : 60, "level" : "及格" }, { "name" : "数学", "score" : 90, "level" : "及格" } ] }
{ "_id" : 3, "name" : "王五", "subjects" : [ { "name" : "英语", "score" : 90, "level" : "及格" }, { "name" : "数学", "score" : 50, "level" : "不及格" } ] }

使用变量时,变量前需要加上 "$$"

如果未定义指向数组中元素的变量,则变量名默认是this

三、数组元素统计($reduce)

语法:

{
    $reduce: {
        input: <array>,
        initialValue: <expression>,
        in: <expression>
    }
}

在数组的每个元素上执行表达式,并将所有的执行结果合并到一起

其中,

        input:代表的是输入的数组

        initialValue:代表的是合并的结果的初始化值

        in:数组中元素需要执行的表达式,表达式中可以使用的变量包括this和value,其中this代表的是指向数组中元素的变量,value代表的是合并的结果。

例子:计算学生的学科总成绩

db.subjects.aggregate([
    {
        $project: {
            "name": 1,
            "subjectTotalScore": {
                $reduce: {
                    input: "$subjects",
                    initialValue: 0,
                    in: { $add: [ "$$value", "$$this.score" ] }
                }
            }
        }
    }
])

我们对上面的聚合查询语法进行解释:

initialValue: 0

        初始化合并的结果value = 0

in: { $add: [ "$$value", "$$this.score" ] }

        将合并的结果value与当前科目的成绩score相加并赋值给合并的结果value

聚合查询的结果如下:

{ "_id" : 1, "name" : "张三", "subjectTotalScore" : 150 }
{ "_id" : 2, "name" : "李四", "subjectTotalScore" : 150 }
{ "_id" : 3, "name" : "王五", "subjectTotalScore" : 140 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值