MongoDB: 创建聚合管道

MongoDB: Create an aggregation pipeline

在 MongoDB 聚合框架中,我希望在地图上使用 $unwind 运算符。看来不可能了。

case class MatchStatus(
    totalRows: Int,
    fullMatch: Int,
    noMatch: Int,
    partialMatch: Int
)

这是示例 JSON,其中我有 matchStatus => Map

{
    "_id" : ObjectId("61e8c7bbd0597207179faa89"),
    "clientId" : "DEMO",
    "matchStatus" : {
        "summary" : {
            "totalRows" : "10",
            "fullMatch" : "5",
            "noMatch" : "1",
            "partialMatch" : "4"
        },
        "income" : {
            "totalRows" : "10",
            "fullMatch" : "1",
            "noMatch" : "0",
            "partialMatch" : "1"
        }
    },
    "date" : "18-01-2022"
},
{
    "_id" : ObjectId("61e8c7bbd0597207179faa89"),
    "clientId" : "DEMO-1",
    "sizes" : [ 
        "1", 
        "2"
    ],
    "matchStatus" : {
        "summary" : {
            "totalRows" : "10",
            "fullMatch" : "5",
            "noMatch" : "1",
            "partialMatch" : "4"
        },
        "income" : {
            "totalRows" : "10",
            "fullMatch" : "1",
            "noMatch" : "0",
            "partialMatch" : "1"
        },
        "slip" : {
            "totalRows" : "10",
            "fullMatch" : "1",
            "noMatch" : "0",
            "partialMatch" : "1"
        },
    },
    "date" : "18-01-2022"
}

So the output I want is =>

{
"summary":{
     "totalRows" : "20",
      "fullMatch" : "10",
      "noMatch" : "2",
      "partialMatch" : "8"
},
"income":{
     "totalRows" : "20",
      "fullMatch" : "10",
      "noMatch" : "0",
      "partialMatch" : "2"
},
"slip":{
     "totalRows" : "10",
      "fullMatch" : "1",
      "noMatch" : "0",
      "partialMatch" : "1"
}
}

Or something similar to this where I fetch the key (summary, income, slip) and total the values.

Tried $unwind but did not work on the map structure.

也许有一个更小的集合体

db.collection.aggregate([
  {
    "$match": {
      "_id": {
        "$in": [
          ObjectId("61e8c7bbd0597207179faa89"),
          ObjectId("61e8c7bbd0597207179faa90")
        ]
      }
    }
  },
  {
    "$set": {
      "matchStatus": {
        $objectToArray: "$matchStatus"
      }
    }
  },
  {
    "$unwind": "$matchStatus"
  },
  {
    "$replaceRoot": {
      "newRoot": "$matchStatus"
    }
  },
  {
    "$set": {
      "v": {
        $objectToArray: "$v"
      }
    }
  },
  {
    "$unwind": "$v"
  },
  {
    "$group": {
      "_id": {
        k1: "$k",
        k2: "$v.k"
      },
      "sum": {
        "$sum": {
          "$toInt": "$v.v"
        }
      }
    }
  },
  {
    "$group": {
      "_id": "$_id.k1",
      "field": {
        "$push": {
          k: "$$ROOT._id.k2",
          v: "$$ROOT.sum"
        }
      }
    }
  },
  {
    "$project": {
      "v": {
        $arrayToObject: "$field"
      }
    }
  },
  {
    "$group": {
      "_id": null,
      "field": {
        "$push": {
          k: "$$ROOT._id",
          v: "$$ROOT.v"
        }
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        $arrayToObject: "$field"
      }
    }
  }
])

mongoplayground