The custom aggregate expression operator mainly completes more complex aggregate query operations by customizing some Javascript functions; in this article, we mainly introduce the use of $function :
1. Preparation
Initialize course grade data
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 }
])
Two, $function
grammar:
{
$function: {
body: <code>,
args: <array expression>,
lang: "js"
}
}
body: function, receiving parameters from args
function(arg1, arg2, ...) { ... }
args: parameter list
[ <arg1>, <arg2>, ... ]
lang: the language used, currently only supports js
$function can only be used in 4.4 and later versions
3. Example: Calculate the grade of the student's grade
Grade requirements:
A: 90 points and above
B: 80 points and above
C: 70 points and above
D: 60 points and above
E: Below 60 points
Aggregation queries are as follows:
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"
}
}
}
}
])
Take the score in the input document as the parameter of the function, execute the function and return the execution result.
The aggregation query above is equivalent to:
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"
}
}
}
}
])
The results of the aggregation query are as follows:
{ "_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" }