поиск древовидной иерархии в монго - PullRequest
0 голосов
/ 10 июля 2020

у меня есть коллекции, которые представляют собой древовидные коллекции метаданных, сайтов и геолокации, одна мета может иметь несколько сайтов, а один сайт может иметь несколько геолокаций

коллекция метаданных

{
    "_id": "1",
    "meta_id": 1,
    "meta_name": "yankung"
}

коллекция сайтов

{
    "_id": "1",
    "meta_id": 1,
    "site_id" :2,
    "site_name": "uoop"
}

Географическая коллекция

{
    "_id": "1",
    "site_id": 2,
    "geo_id" :3,
    "geo_name": "toop"
}

Мне нужно получить такой конечный результат

{
  "_id": "1",
  "meta_id": 1,
  "meta_name": "yankung",
  "sites": [
    {
      "site_id": 2,
      "site_name": "uoop",
      "geos:": [
        {
          "geo_id": 3,
          "geo_name": "toop"
        },
        {
          "geo_id": 4,
          "geo_name": "toop"
        }
      ]
    },
    {
      "site_id": 1000,
      "site_name": "uoop",
      "geos:": [
        {
          "geo_id": 5,
          "geo_name": "toop"
        },
        {
          "geo_id": 6,
          "geo_name": "toop"
        }
      ]
    }
  ]
}

Я попытался использовать агрегационный запрос с поиском, и раскрутка смогла разделить сайты и географические объекты в виде списка, подумать о получении требуемого результата на уровне приложения, но придется перебирать каждый документ и добавлять, что увеличит временную сложность, любая помощь в том, как мне действовать?

это что я смог достичь

{
  "_id": "1",
  "meta_id": 1,
  "meta_name": "yankung",
  "sites": [
    { "site_id": 2, "site_name": "uoop"
    },
    {"site_id": 1000,"site_name": "uoop"
    }
      ],
   "geos:": [
        { "geo_id": 5,"geo_name": "toop"
        },
        {"geo_id": 6,"geo_name": "toop"
        }
  ]
}

1 Ответ

1 голос
/ 11 июля 2020

Хитрость заключается в использовании $ поиска с условиями соединения и некоррелированными подзапросами . Таким образом, вы можете определить $ lookup внутри $ lookup.

Вот запрос:

db.meta_collection.aggregate([
  {
    $lookup: {
      from: "site_collection",
      let: {
        meta: "$meta_id"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $eq: [
                "$meta_id",
                "$$meta"
              ]
            }
          }
        },
        {
          $lookup: {
            from: "geo_collection",
            let: {
              site: "$site_id"
            },
            pipeline: [
              {
                $match: {
                  $expr: {
                    $eq: [
                      "$site_id",
                      "$$site"
                    ]
                  }
                }
              },
              
            ],
            as: "geos"
          }
        }
      ],
      as: "sites"
    }
  }
])

Вы можете протестировать его здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...