MongoDB聚合然后展平

MongoDB aggregate and then flatten

完全披露:我是一个 MongoDB 菜鸟

我正在处理遗留数据库结构。我的 MongoDB 的一部分目前看起来像这样:

关系如下:

我需要以给定 eventId 的方式进行查询,我 return

Order ID
Customer Name (can be a cascade request / premeditated by frontend),
Product SKU,
Product Name,
Quantity,
Value (quantity * price),
Signee Name,
Sign time

请注意,我的界面需要对上述所有字段进行过滤和排序,以及分页的限制和偏移量,以减少查询时间、快速 UI 等

我可以在订单上使用 populate,但我应该如何通过 mongoose 遵守限制和抵消。我想知道我是否应该制作一个视图,在这种情况下我应该如何将它展平为 send/receive 一个遵守限制和偏移量的列表。

还是必须非常手动地逐步构建结果列表?

更新:

数据库中的示例数据:

事件对象:

{ 
    "_id" : ObjectId("6218b9266487367ba1c20258"), 
    "name" : "XYZ", 
    "createdAt" : ISODate("2022-02-03T13:25:43.814+0000"), 
    "updatedAt" : ISODate("2022-02-14T09:34:47.819+0000"),
    ...
}

订单:

[
{ 
    "_id" : ObjectId("613ae653d0112f6b49fdd437"), 
    "orderItems" : [
        {
            "quantity" : NumberInt(2), 
            "productCode" : "VEO001", 
        }, 
        {
            "quantity" : NumberInt(2), 
            "productCode" : "VEO002", 
        }, 
        {
            "quantity" : NumberInt(1), 
            "productCode" : "VEO003", 
        }
    ], 
    "orderCode" : "1000", 
    "customerCode" : "Customer 1", 
    "createdAt" : ISODate("2021-09-10T05:00:03.496+0000"), 
    "updatedAt" : ISODate("2022-02-08T10:06:42.255+0000"), 
    "eventId" : "6218b9266487367ba1c20258"
}
]

产品:

[
{ 
    "_id" : ObjectId("604206685f25b8560a1cd48d"), 
    "Product name" : "ABC", 
    "createdAt" : ISODate("2021-03-05T10:22:32.085+0000"), 
    "tag" : "VEO001", 
    "updatedAt" : ISODate("2022-03-28T07:29:21.939+0000"), 
    "Product Price" : NumberInt(0), 
    "photo" : {
        "_id" : ObjectId("6042071a5f25b8560a1cd4a9"), 
        "key" : "e8c9a085-4e8d-4ac4-84e9-bb0a83a59145", 
        "name" : "Screenshot 2021-03-05 at 11.24.50.png"
    }, 
    "name" : "ABC", 
    "_costprice" : NumberInt(12), 
    "_sku" : "SKUVEO001",
},
{ 
    "_id" : ObjectId("604206685f25b8560a1cd48a"), 
    "Product name" : "DEF", 
    "createdAt" : ISODate("2021-03-05T10:22:32.085+0000"), 
    "tag" : "VEO002", 
    "updatedAt" : ISODate("2022-03-28T07:29:21.939+0000"), 
    "Product Price" : NumberInt(0), 
    "photo" : {
        "_id" : ObjectId("6042071a5f25b8560a1cd4a9"), 
        "key" : "e8c9a085-4e8d-4ac4-84e9-bb0a83a59145", 
        "name" : "Screenshot 2021-03-05 at 11.24.50.png"
    }, 
    "name" : "DEF", 
    "_costprice" : NumberInt(13), 
    "_sku" : "SKUVEO002",
},
{ 
    "_id" : ObjectId("604206685f25b8560a1cd48a"), 
    "Product name" : "GHI", 
    "createdAt" : ISODate("2021-03-05T10:22:32.085+0000"), 
    "tag" : "VEO003", 
    "updatedAt" : ISODate("2022-03-28T07:29:21.939+0000"), 
    "Product Price" : NumberInt(0), 
    "photo" : {
        "_id" : ObjectId("6042071a5f25b8560a1cd4a9"), 
        "key" : "e8c9a085-4e8d-4ac4-84e9-bb0a83a59145", 
        "name" : "Screenshot 2021-03-05 at 11.24.50.png"
    }, 
    "name" : "GHI", 
    "_costprice" : NumberInt(13), 
    "_sku" : "SKUVEO003",
},
]

预期输出:

您可以这样做:

db.orders.aggregate([
  {$match: {eventId: "6218b9266487367ba1c20258"}},
  {
    $lookup: {
      from: "products",
      localField: "orderItems.productCode",
      foreignField: "tag",
      as: "orderItemsB"
    }
  },
  {
    "$addFields": {
      "orderItems": {
        "$map": {
          "input": "$orderItemsB",
          "in": {
            "$mergeObjects": [
              "$$this",
              {
                "$arrayElemAt": [
                  "$orderItems",
                  {"$indexOfArray": ["$orderItems.productCode", "$$this.tag"]}
                ]
              }
            ]
          }
        }
      },
      orderItemsB: 0
    }
  },
  {
    $unset: "orderItemsB"
  },
  {
    $lookup: {
      from: "events",
      let: {eventId: "$eventId"},
      pipeline: [
        {
          $match: {$expr: {$eq: [{$toString: "$_id"}, "$$eventId"]}}
        }
      ],
      as: "event"
    }
  },
  {
    $set: {event: {"$arrayElemAt": ["$event", 0]}}   
  },
  {$unwind: "$orderItems"}
])

正如您在 this playground example 上看到的那样。这将为您提供包含所有数据的订单中每个产品的文档。