在 Mongo Java 中分组后对多级数组进行排序

Sort multiple levels of array after group in Mongo Java

我有以下架构的文档

id : 
currencyCode : "USD"
businessDayStartDate : ""
hourZoneNumber : 1
customerCount : 0
itemQuantity : 4
nodeId : "STORE_DEV"
endpointId : "998"
amount : 4

我正在尝试查找与 nodeId 匹配的文档,并尝试聚合每个 hourZoneNumber 的 customerCount、itemQuantity 和金额。

下面是查询

db.getCollection("xxx").aggregate([
{ "$match": { "nodeId": { "$in":["STORE_DEV_1","STORE_DEV_2"] }, "businessDayStartDate" : { "$gte": "2022-03-04" , "$lte": "2022-03-07" } }},
{ "$group": {
       "_id": {
          "nodeId": "$nodeId",
          "endpointId": "$endpointId",
          "hourZoneNumber": "$hourZoneNumber"
       },
       "customerCount": { "$sum": "$customerCount" },
       "itemQuantity" : { "$sum": "$itemQuantity" },
       "amount" : { "$sum": "$amount" }
       
  }
},
{ "$group": {
       "_id": {
          "nodeId": "$_id.nodeId",
          "endpointId": "$_id.endpointId"
       },
       "hourZones": {
          "$addToSet": {
            "hourZoneNumber": "$_id.hourZoneNumber",
            "customerCount": { "$sum": "$customerCount" },
            "itemQuantity" : { "$sum": "$itemQuantity" },
            "amount" : { "$sum": "$amount" }
          }
       }
       
  }
},
{ "$group": {
       "_id": "$_id.nodeId",
       "endpoints": {
          "$addToSet": {
            "endpointId": "$_id.endpointId",
             "hourZones": "$hourZones"
          }
       },
       "total": {
            "$addToSet": {
                "customerCount": { "$sum": "$hourZones.customerCount" },
                "itemQuantity" : { "$sum": "$hourZones.itemQuantity" },
                "amount" : { "$sum": "$hourZones.amount" }
          }
       }
  }
},
{
    $project: {
      _id: 0,
      nodeId: "$_id",
      endpoints: 1,
      hourZones: 1,
      total: 1
    }
  }
])

输出如下:

{
  nodeId: 'STORE_DEV_2',
  endpoints: [ 
    { endpointId: '998',
       hourZones: 
        [ 
          { hourZoneNumber: 1,
            customerCount: 0,
            itemQuantity: 4,
            amount: Decimal128("4") }
        ] } ],
  total: [ { customerCount: 0, itemQuantity: 4, amount: Decimal128("4") } ],
}
{ 
  nodeId: 'STORE_DEV_1',
  endpoints: 
   [ { endpointId: '999',
       hourZones: 
        [ { hourZoneNumber: 2,
            customerCount: 2,
            itemQuantity: 4,
            amount: Decimal128("4") },
          { hourZoneNumber: 1,
            customerCount: 4,
            itemQuantity: 8,
            amount: Decimal128("247.56") } ] } ],
  total: 
   [ { customerCount: 6,
       itemQuantity: 12,
       amount: Decimal128("251.56") } ]
}

我希望输出排序为:首先按 nodeId 排序,然后按端点内的 endpointId 排序,最后按 hourZones 内的 hourZoneNumber 排序。

我该怎么做?我尝试对所有三个字段使用 sort() 。但它没有用。另外,有人可以确认是否有比上述代码更好的方法,因为我是 Mongo 数据库的新手。

编辑: 请在 https://mongoplayground.net/p/FYm3QMMgrNI

找到示例输入数据

因为一开始就已经有了分离的数据,所以只需要通过分组保存这些值,最后按它们排序即可。

编辑:为了对每个内部数组进行排序,我们在每个 $group 之前使用 $push 而不是 $group$sort 中的 $addToSet

db.collection.aggregate([
  {
    "$match": {
      "nodeId": {"$in": ["STORE_DEV_TTEC", "STORE_DEV_TTEZ"]
      },
      "businessDayStartDate": {"$gte": "2022-03-04", "$lte": "2022-03-07"}
    }
  },
  {
    "$sort": {"nodeId": 1, "endpointId": 1, "hourZoneNumber": 1}
  },
  {
    "$group": {
      "_id": {
        "nodeId": "$nodeId",
        "endpointId": "$endpointId",
        "hourZoneNumber": "$hourZoneNumber"
      },
      "customerCount": {"$sum": "$customerCount"},
      "itemQuantity": {"$sum": "$itemQuantity"},
      "amount": {"$sum": "$amount"}
    }
  },
  {"$sort": {"_id.hourZoneNumber": 1}
  },
  {
    "$group": {
      "_id": {
        "nodeId": "$_id.nodeId",
        "endpointId": "$_id.endpointId"
      },
      "hourZones": {
        "$push": {
          "hourZoneNumber": "$_id.hourZoneNumber",
          "customerCount": {"$sum": "$customerCount"},
          "itemQuantity": {"$sum": "$itemQuantity"},
          "amount": {"$sum": "$amount"}
        }
      },
      hourZoneKey: {$first: "$_id.hourZoneNumber"}
    }
  },
  {"$sort": {"_id.endpointId": 1}
  },
  {
    "$group": {
      "_id": "$_id.nodeId",
      "endpoints": {
        "$push": {
          "endpointId": "$_id.endpointId",
          "hourZones": "$hourZones"
        }
      },
      endpointKey: {$first: "$_id.endpointId"},
      hourZoneKey: {$first: "$hourZoneKey"}
    }
  },
  {"$sort": {"nodeId": 1, "endpointKey": 1, "hourZoneKey": 1}
  },
  {
    $project: {_id: 0, nodeId: "$_id", endpoints: 1, hourZones: 1, total: 1}
  }
])

可以看到here