Многоуровневый поиск агрегатов в БД Монго

Итак, вот моя упрощенная структура данных:

Тест (тест):

[{
   _id:1,
   name:"test1"
}]

Расписание тестов (test_scheduled):

[{
   _id:2,
   testId:1,
   batchIds:[1,2]
}]

Пакет (партия):

[{
    _id:1,
    name:"batch 1" 
},{
    _id:2,
    name:"batch 2"
}]

Вот как мне нужно, чтобы результат выглядел следующим образом:

{ // Test
    _id:1,
    name:"test1",
    test_scheduled:[{ // test scheduled
       _id:2,
       batches:[{ // batches
          _id:1,
          name:"batch 1"
       },{
          _id:2,
          name:"batch 2"
       }]
    }]
}

Я могу достичь поиска первого уровня, используя это:

 [ // querying test collection
  {
    $lookup:{
      from: "tests_scheduled",
      localField: "_id",
      foreignField: "testId",
      as: "tests_scheduled"
    }
  },
  {
    $match:{
      _id:new DB.Mongo.ObjectID(testId)
    }
  }
]

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

Спасибо за вашу помощь

Всего 1 ответ


Вы можете использовать агрегацию ниже, если вы используете mongodb 3.6 и выше

Test.aggregate([
  { "$match": { "_id": new DB.Mongo.ObjectID(testId) }},
  { "$lookup": {
    "from": TestScheduled.collection.name,
    "let": { "testId": "$_id" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": [ "$testId", "$$testId" ] } } },
      { "$lookup": {
        "from": Batch.collection.name,
        "let": { "batchIds": "$batchIds" },
        "pipeline": [
          { "$match": { "$expr": { "$in": [ "$_id", "$$batchIds" ] } } }
        ],
        "as": "batches"
      }}
    ],
    "as": "test_scheduled"
  }}
])

MongoPlayground

Или, если вы используете версию до 3.6

Test.aggregate([
  { "$match": { "_id": new DB.Mongo.ObjectID(testId) }},
  { "$lookup":{
    "from": TestScheduled.collection.name,
    "localField": "_id",
    "foreignField": "testId",
    "as": "tests_scheduled"
  }},
  { "$unwind": "$tests_scheduled" },
  { "$lookup":{
    "from": Batch.collection.name,
    "localField": "tests_scheduled.batchIds",
    "foreignField": "_id",
    "as": "tests_scheduled.batches"
  }},
  { "$group": {
    "_id": "$_id",
    "tests_scheduled": { "$push": "$tests_scheduled" }
  }}
])

MongoPlayground


Есть идеи?

10000