Use custom aggregation expression operator ($function) in MongoDB aggregation pipeline

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" }

Guess you like

Origin blog.csdn.net/m1729339749/article/details/130597563