【问题标题】:deep mongodb aggregate to make Groups with the common fields in array of objects?深 mongodb 聚合以在对象数组中创建具有公共字段的组?
【发布时间】:2020-07-31 13:11:59
【问题描述】:

我想使用 mongodb 聚合来创建组。我想在我的项目中实现这一点,但陷入了困境。没有找到更好的方法来做到这一点。


{
    "_id" : ObjectId("5e9a21868ed974259c0da402"),
    "shopId" : "5e975cc7be7c1b546b7abb17",
    "shopType" : "Medium Store",
        "products": [{
            "isPackedProduct" : true,
            "_id" : ObjectId("5e92ff706af877294d63098e"),
            "brand" : "ABC",
            "category" : "CAT1",
            "productName" : "P1",
            "subCategory" : "SUB1",
        },
        {
            "isPackedProduct" : true,
            "_id" : ObjectId("5e92ff706af877294d63098f"),
            "brand" : "EFG",
            "category" : "CAT1",
            "productName" : "P2",
            "subCategory" : "SUB2",
        },
        {
            "isPackedProduct" : true,
            "_id" : ObjectId("5e92ff706af84d630977298f"),
            "brand" : "EFG",
            "category" : "CAT2",
            "productName" : "P3",
            "subCategory" : "SUB1",
        }
        ....
     ]    
}

从这组 json 中我想将数据显示为:


   {
     "_id" : ObjectId("5e9a21868ed974259c0da402"),
     "shopId" : "5e975cc7be7c1b546b7abb17",
     "CAT1":{
       "SUB1":{
          "products": [{
            ...ALL the Products which have CAT1 and SUB1
          }]
        }
     },
     "CAT2":{
       "SUB1":{
          "products": [{
            ...ALL the Products which have CAT2 and SUB1
          }]
        }
     }
     ...
   }


到目前为止,我尝试了但没有接近解决方案:

db.shopproducts.aggregate([{$unwind: {path: '$products'}}, {$group: {_id: 'products.category'}}, {$project: {'products.category': 1, 'products.productName': 1}}])

此外,如果有更好的方法可以在不使用聚合的情况下执行此操作,那么欢迎提出建议。

提前致谢。

【问题讨论】:

    标签: node.js mongodb mongoose aggregate


    【解决方案1】:

    我们需要应用几个$group 阶段。要将products.categoryproducts.subCategory 转换为对象字段,我们需要使用$arrayToObject 运算符。

    [                                        {
      { "k" : "CAT1", "v" : "SUB1" }, ----\     "CAT1" : "SUB1",
      { "k" : "CAT2", "v" : "SUB1" }  ----/     "CAT2" : "SUB1"
    ]                                        }
    

    试试这个:

    db.shopproducts.aggregate([
      {
        $unwind: "$products"
      },
      {
        $group: {
          _id: {
            _id: "$_id",
            shopId: "$shopId",
            category: "$products.category",
            subCategory: "$products.subCategory"
          },
          products: {$push: "$products"}
        }
      },
      {
        $group: {
          _id: {
            _id: "$_id._id",
            shopId: "$_id.shopId",
            category: "$_id.category"
          },
          products: {
            $push: {
              k: "$_id.subCategory",
              v: {products: "$products"}
            }
          }
        }
      },
      {
        $group: {
          _id: {
            _id: "$_id._id",
            shopId: "$_id.shopId"
          },
          products: {
            $push: {
              k: "$_id.category",
              v: {$arrayToObject: "$products"}
            }
          }
        }
      },
      {
        $replaceRoot: {
          newRoot: {
            $mergeObjects: [
              {
                _id: "$_id._id",
                shopId: "$_id.shopId"
              },
              {
                $arrayToObject: "$products"
              }
            ]
          }
        }
      }
    ])
    

    MongoPlayground

    【讨论】:

      【解决方案2】:
      db.shopproducts.aggregate([
        {
          $unwind: {
            path: "$products"
          }
        },
        {
          $group: {
            _id: {
              cat: "$products.category",
              sub_cat: "$products.subCategory"
            },
            products: {
              $addToSet: "$products"
            }
          }
        }
      ])
      

      我猜这就是你想要的,不是吗?

      Mongoplayground

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-14
        • 1970-01-01
        • 2020-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-13
        相关资源
        最近更新 更多