自定义聚合表达式运算符主要通过自定义一些Javascript函数来完成更加复杂的聚合查询操作;本篇我们主要介绍$function的使用:
一、准备工作
初始化课程成绩数据
db.subjectScores.insertMany([
{ "_id": 1, "name": "张三", "subject": "eng", "score": 80 },
{ "_id": 2, "name": "李四", "subject": "eng", "score": 60 },
{ "_id": 3, "name": "王五", "subject": "eng", "score": 90 },
{ "_id": 4, "name": "张三", "subject": "math", "score": 70 },
{ "_id": 5, "name": "李四", "subject": "math", "score": 90 },
{ "_id": 6, "name": "王五", "subject": "math", "score": 50 },
{ "_id": 7, "name": "张三", "subject": "physics", "score": 80 },
{ "_id": 8, "name": "李四", "subject": "physics", "score": 60 },
{ "_id": 9, "name": "王五", "subject": "physics", "score": 70 }
])
二、$function
语法:
{
$function: {
body: <code>,
args: <array expression>,
lang: "js"
}
}
body:函数,从args中接收参数
function(arg1, arg2, ...) { ... }
args:参数列表
[ <arg1>, <arg2>, ... ]
lang: 使用的语言,目前仅支持js
$function 在4.4及以后的版本中才能使用
三、例子:计算学生的成绩的等级
等级要求:
A: 90分及以上
B: 80分及以上
C: 70分及以上
D: 60分及以上
E: 60分以下
聚合查询如下:
db.subjectScores.aggregate([
{
$project: {
"name": 1,
"subject": 1,
"score": 1,
"scoreLevel": {
$function: {
body: function(s) {
if(s >= 90) {
return "A";
} else if(s >= 80) {
return "B";
} else if(s >= 70) {
return "C";
} else if(s >= 60) {
return "D";
} else {
return "E";
}
},
args: [ "$score" ],
lang: "js"
}
}
}
}
])
将输入文档中的score作为函数的参数,执行函数并将执行的结果返回。
上面的聚合查询等效于:
db.subjectScores.aggregate([
{
$project: {
"name": 1,
"subject": 1,
"score": 1,
"scoreLevel": {
$switch: {
branches: [
{ case: { $gte: [ "$score", 90 ] }, then: "A" },
{ case: { $gte: [ "$score", 80 ] }, then: "B" },
{ case: { $gte: [ "$score", 70 ] }, then: "C" },
{ case: { $gte: [ "$score", 60 ] }, then: "D" },
],
default: "E"
}
}
}
}
])
聚合查询的结果如下:
{ "_id" : 1, "name" : "张三", "subject" : "eng", "score" : 80, "scoreLevel" : "B" }
{ "_id" : 2, "name" : "李四", "subject" : "eng", "score" : 60, "scoreLevel" : "D" }
{ "_id" : 3, "name" : "王五", "subject" : "eng", "score" : 90, "scoreLevel" : "A" }
{ "_id" : 4, "name" : "张三", "subject" : "math", "score" : 70, "scoreLevel" : "C" }
{ "_id" : 5, "name" : "李四", "subject" : "math", "score" : 90, "scoreLevel" : "A" }
{ "_id" : 6, "name" : "王五", "subject" : "math", "score" : 50, "scoreLevel" : "E" }
{ "_id" : 7, "name" : "张三", "subject" : "physics", "score" : 80, "scoreLevel" : "B" }
{ "_id" : 8, "name" : "李四", "subject" : "physics", "score" : 60, "scoreLevel" : "D" }
{ "_id" : 9, "name" : "王五", "subject" : "physics", "score" : 70, "scoreLevel" : "C" }