как получить данные, используя агрегат с динамическим сбором с массивом _id - PullRequest
0 голосов
/ 04 июня 2019

Мне нужно получить данные из динамического сбора, например, если type = category, а затем извлечь данные из коллекции категорий, если type = banner получить данные из баннера.

Массив входных данных:

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

Ожидаемый выходной массив:

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

1 Ответ

1 голос
/ 04 июня 2019

Лучшее, что вы можете сделать, это использовать $ facet , чтобы разбить его на несколько различных агрегаций, а затем "объединить" их обратно в требуемую структуру.

Это будет выглядеть примерно так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"}
  }
}

Обратите внимание, что я попытался сделать эту агрегацию более удобочитаемой, что означает, что она не настолько эффективна, как могла бы.

...