глубокий агрегат mongodb, чтобы сделать группы с общими полями в массиве объектов? - PullRequest
0 голосов
/ 18 апреля 2020

Я хочу сделать из этого группы, используя агрегат 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}}])

Кроме того, если есть лучший способ сделать это без использования агрегата, тогда предложения приветствуются.

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Нам нужно применить несколько $group этапов. Чтобы преобразовать products.category и products.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

1 голос
/ 18 апреля 2020
db.shopproducts.aggregate([
  {
    $unwind: {
      path: "$products"
    }
  },
  {
    $group: {
      _id: {
        cat: "$products.category",
        sub_cat: "$products.subCategory"
      },
      products: {
        $addToSet: "$products"
      }
    }
  }
])

Полагаю, это то, что вы хотите, не так ли?

Mongoplayground

...