MongoDB -如何对所有主题标记求和

mwg9r5ms  于 2022-11-22  发布在  Go
关注(0)|答案(1)|浏览(97)

我想把studentMarkDetails数组中所有科目的分数相加。我该怎么做呢?它在studentMarkDetails数组中,如果我使用$unwind,我会得到0条记录。
我需要这样的输出:

{
    "_id": ObjectId("636efe231eeef2f46a31d7f4"),
    "sName": "Somu",
    "class": "tenth",
    "year": 2003,
    "examType": "quaterly",
    "total_marks": 300
}

我的文档是:

{
    "_id": ObjectId("636efe231eeef2f46a31d7f4"),
    "sName": "Somu",
    "class": "tenth",
    "year": 2003,
    "studentMarkDetails": [ 
        {
            "examType": "quaterly",
            "marks": {
                "Eng": 55,
                "Tel": 45,
                "Mat": 75,
                "Sec": 43,
                "Soc": 65
            }
        }, 
        {
            "examType": "halfyearly",
            "marks": {
                "Eng": 56,
                "Tel": 76,
                "Mat": 89,
                "Sec": 34,
                "Soc": 76
            }
        }, 
        {
            "examType": "final",
            "marks": {
                "Eng": 89,
                "Tel": 78,
                "Mat": 91,
                "Sec": 95,
                "Soc": 87
            }
        }
    ]
}
5jdjgkvh

5jdjgkvh1#

有几种方法可以实现预期的输出,解决方案的关键是需要通过$objectToArraymarks对象转换为数组,然后执行求和。

解决方案1

  1. $project -
    1.1. $sum?对结果 1.1.1 中得数组值求和.
    1.1.1. $map-迭代数组中的每个元素并生成一个新数组。
    1.1.1.1. input-将marks对象转换为对象数组(格式:{ k: "Eng", v: 89 })的数据。
    1.1.1.2. in-返回v
db.collection.aggregate([
  {
    $unwind: "$studentMarkDetails"
  },
  {
    $project: {
      "sName": 1,
      "class": 1,
      "year": 1,
      "examType": "$studentMarkDetails.examType",
      "total_marks": {
        $sum: {
          $map: {
            input: {
              $objectToArray: "$studentMarkDetails.marks"
            },
            in: "$$this.v"
          }
        }
      }
    }
  }
])

Demo Solution 1 @ Mongo Playground

解决方案2

您也可以使用$reduce,它的目的是将一个数组转换为一个新值。结果将与 Solution 1 相同。

db.collection.aggregate([
  {
    $unwind: "$studentMarkDetails"
  },
  {
    $project: {
      "sName": 1,
      "class": 1,
      "year": 1,
      "examType": "$studentMarkDetails.examType",
      "total_marks": {
        $reduce: {
          input: {
            $objectToArray: "$studentMarkDetails.marks"
          },
          initialValue: 0,
          in: {
            $sum: [
              "$$value",
              "$$this.v"
            ]
          }
        }
      }
    }
  }
])

Demo Solution 2 @ Mongo Playground

相关问题