Nirav Sutariya
Nirav Sutariya

Reputation: 307

how to fetch data using aggregate with dynamic collection with array of _id's

i need get data from dynamic collection like if type = category then fetch data from category collection if type = banner the fetch data from banner.

Input Data Array:

[
 {
  "title": "New Product",
  "row_data": [
   {
    "type": "category",
    "data": [
      5cf4edcdc70d4716d821d45d,5cf4ee36c70d4716d821d460
    ]
   },
   {
    "type": "banner",
    "data": [
     5ce4eb55b02bd01ca09eb909
    ]
   },
   {
    "type": "product",
    "data": [
     5cf4eed8c70d4716d821d465,5cf4fa09c70d4716d821d483
    ]
   }
  ],
  "_id": "5cf611c7fcc98b16b0e89200"
 }
]

Expected Output Array:

[
 {
  "title": "New Product",
  "row_data": [
   {
    "type": "category",
    "data": [{_id: 5cf4edb7c70d4716d821d45c, image: "image.jpg", title: "Saree"},{_id: 5cf4edcdc70d4716d821d45d, image: "image.jpg", title: "Kurti"}]
   },
   {
    "type": "banner",
    "data": [{_id: 5ce4eb55b02bd01ca09eb909, name: "first banner", image: "banner-image.jpg"}]
   },
   {
    "type": "product",
    "data": [{_id: 5cf4eed8c70d4716d821d465, image: "image.jpg", sku: "S-01"},{_id: 5cf4fa09c70d4716d821d483, image: "image.jpg", sku: "K-01"}]
   }
  ],
  "_id": "5cf611c7fcc98b16b0e89200"
 }
]

Upvotes: 0

Views: 120

Answers (1)

Tom Slabbaert
Tom Slabbaert

Reputation: 22316

The best you can do is use $facet to split it into several different aggregations, and then "merge" them back to the required structure.

It would look a little like this:

{
   $unwind: "$row_data"
},   
{
  $facet: {
     categories: [{
         $lookup:{
           from: "categories",
           let: { ids: "$row_data.data"},
           pipeline: [
              { $match:
                 { $expr:
                    { 
                        $in: ["$_id", "$$ids"]
                    }
                 }
              },
           ],
           as: "match"
         }},
         {
           $match: {
              'match.0': {$exists: true}
           } 
         },
         {
            $addFields: {
                 temp: {type: 'category', data: '$match'}
            }
        }
     ],
     banners: [{
         $lookup:{
           from: "banner",
           let: { ids: "$row_data.data"},
           pipeline: [
              { $match:
                 { $expr:
                    { 
                        $in: ["$_id", "$$ids"]
                    }
                 }
              },
           ],
           as: "match"
         }},
         {
           $match: {
              'match.0': {$exists: true}
           } 
        },
        {
            $addFields: {
                 temp: {type: 'banner', data: '$match'}
            }
        }
     ],
     ....
  }
},
{
  $addFields: {
    "merged": { $concatArrays: [ "$categories", "$banners", ...] }
  }
},
{
 $unwind: "$merged"
},
{
  $group: {
     _id: "$merged._id",
     title: {$first: "$merged.title"},
     row_data: {$push: "$merged.temp"}
  }
}

Note that i tried to make this aggregation more read-able meaning its not as efficient as it can be.

Upvotes: 1

Related Questions