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

发布于 2025-01-16 21:20:27 字数 2959 浏览 1 评论 0原文

我有具有以下架构的文档,

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 DB 的新手。

编辑: 请在 https://mongoplayground.net/p/FYm3QMMgrNI 查找示例输入数据

I have documents with below schema

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

I am trying to find documents that match nodeId and trying to aggregate customerCount, itemQuantity and amount for each hourZoneNumber.

Below is the query

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
    }
  }
])

Output is as below:

{
  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") } ]
}

I want the output to be sorted as : First sort by nodeId, then by endpointId within the endpoints and lastly by hourZoneNumber within hourZones.

How do I do this ? I tried using sort() with all the three fields. But it did not work. Also, can someone please confirm if there is any better way than the above code, as I am new to Mongo DB.

Edit:
Please find sample input data at https://mongoplayground.net/p/FYm3QMMgrNI

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

早乙女 2025-01-23 21:20:27

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

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

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}
  }
])

您可以此处查看它

Since you already have the separated data at the beginning, it is simply a matter of saving these values through the grouping and then sorting by them in the end.

Edit: In order to sort each inner array, we use $push instead of $addToSet inside the $group and $sort before each $group:

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}
  }
])

You can see it here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文