$агрегация поиска для объекта вложенного массива

#mongodb #mongodb-query #aggregation-framework

Вопрос:

У меня есть category коллекция, в которую встроен объект подкатегории. Мне нужно написать сценарий агрегирования для первого поиска из этой коллекции в storelisting коллекцию. Затем добавьте поля списка магазинов в соответствующие подкатегории.

Категория

 {
  "_id": "",
  "categoryName": "",
  "subCategories": [
    {
      "subCategoryId": "",
      "subCategoryName": "",
      "storeListingIds": [
        "1",
        "2"
      ]
    },
    {
      "subCategoryId": "",
      "subCategoryName": "",
      "storeListingIds": [
        "3","4","5"
      ]
    }
  ],
  "order": 2,
  "createdAt": {
    "$date": "2020-12-01T22:26:11.669Z"
  },
  "updatedAt": {
    "$date": "2021-04-27T17:17:25.442Z"
  },
  "_class": ""
}
 

список магазинов

 {
  "_id": "1",
  "storeListingName": "",
  "storeListingUrl": "",
  "catalogueIds": [
    ""
  ],
  "_class": ""
},
{
  "_id": "2",
  "storeListingName": "",
  "storeListingUrl": "",
  "catalogueIds": [
    ""
  ],
  "_class": ""
},
{
  "_id": "3",
  "storeListingName": "",
  "storeListingUrl": "",
  "catalogueIds": [
    ""
  ],
  "_class": ""
},
{
  "_id": "4",
  "storeListingName": "",
  "storeListingUrl": "",
  "catalogueIds": [
    ""
  ],
  "_class": ""
},
{
  "_id": "5",
  "storeListingName": "",
  "storeListingUrl": "",
  "catalogueIds": [
    ""
  ],
  "_class": ""
}
 

Мне нужно найти форму над коллекцией в коллекции списков хранения. Мне также нужны все поля списка магазинов.

Результат должен выглядеть так:

 {
  "_id": "",
  "categoryName": "",
  "subCategories": [
    {
      "subCategoryId": "",
      "subCategoryName": "",
      "storeListingIds": [
        "1",
        "2"
      ],
      "storeListings":[
        {
          "_id": "1",
          "storeListingName": "",
          "storeListingUrl": "",
          "catalogueIds": [
            ""
          ],
          "_class": ""
        },
        {
          "_id": "2",
          "storeListingName": "",
          "storeListingUrl": "",
          "catalogueIds": [
            ""
          ],
          "_class": ""
        }
      ]
    },
    {
      "subCategoryId": "",
      "subCategoryName": "",
      "storeListingIds": [
        "3","4","5"
      ],
      "storeListings":[
        {
          "_id": "3",
          "storeListingName": "",
          "storeListingUrl": "",
          "catalogueIds": [
            ""
          ],
          "_class": ""
        },
        {
          "_id": "4",
          "storeListingName": "",
          "storeListingUrl": "",
          "catalogueIds": [
            ""
          ],
          "_class": ""
        },
        {
          "_id": "5",
          "storeListingName": "",
          "storeListingUrl": "",
          "catalogueIds": [
            ""
          ],
          "_class": ""
        }
      ]
    }
  ],
  "order": 2,
  "createdAt": {
    "$date": "2020-12-01T22:26:11.669Z"
  },
  "updatedAt": {
    "$date": "2021-04-27T17:17:25.442Z"
  },
  "_class": ""
}
 

Комментарии:

1. Вопрос недостаточно ясен.. К какой коллекции вам нужно присоединиться? Как приходят storeListingName и другие?

2. @varman У нас есть две категории коллекций и список магазинов, нам нужно присоединиться к категории и списку магазинов. Чтобы присоединиться к этому, нам нужно проверить идентификаторы из «Subcategies.storeListingIds». Атрибут storeListingName берется из коллекции storeListing. Это документ коллекции списков магазинов: { «_id»: «4», «Имя списка магазинов»: «», «Список магазинов»: «», «Идентификаторы каталога»: [ «» ], «_класс»: «» }

Ответ №1:

Объяснение

  1. Мы выполняем $lookup для вложенных storeListingId и сохраняем результат в tmp поле
  2. Мы применяем фильтрацию и объединяем subCategories объект со storeListings значениями

Примечание: Причина, по которой мы используем $mergeObjects , заключается в том, чтобы не называть каждое поле в subCategories

 $map: {
    input: "$subCategories",
    as: "subCat",
    in: {
        subCategoryId:"$subCat.subCategoryId",
        subCategoryName:"$subCat.subCategoryName",
        storeListingIds: "$subCat.storeListingIds",
        storeListening: {
            $filter: {
                input: "$tmp",
                cond: {
                  $in: [ "$this._id", "$subCat.storeListingIds" ]
                }
            }
        }
    }
}
 

Попробуйте вот это:

 db.category.aggregate([
  {
    $lookup: {
      from: "storelisting",
      localField: "subCategories.storeListingIds",
      foreignField: "_id",
      as: "tmp"
    }
  },
  {
    $addFields: {
      tmp: "$REMOVE",
      subCategories: {
        $map: {
          input: "$subCategories",
          as: "subCat",
          in: {
            "$mergeObjects": [
              "$subCat",
              {
                storeListings: {
                  $filter: {
                    input: "$tmp",
                    cond: {
                      $in: [ "$this._id", "$subCat.storeListingIds" ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])
 

MongoPlayground