Mongodb совокупный поиск для многих коллекций в один вложенный вывод - PullRequest
0 голосов
/ 04 мая 2018

У меня есть 3 коллекции:

Школа

{   "id" : { "$numberLong" : "100000" },         
    "name" : "School1" }

Факультет

{   "id" : { "$numberLong" : "100000" }, 
    "schoolId" : { "$numberLong" : "100000" }, 
    "name" : "Faculty1" }

Тема

{   "id" : { "$numberLong" : "100000" },       
    "name" : "Subject1" }

Предположим, их много в каждой коллекции. Я хочу иметь возможность обслуживать конечную точку, которая получает ID и возвращает полную трехуровневую иерархию (Школа-> Факультет-> Предмет). Как бы я вернул все эти данные.

Что-то вроде:

{
    id: 1,
    name: "school1", 
    faculties: [{
        id:1000, 
        name: "faculty1", 
        subjects: [
            {id: 1, name: "sub1"},
            {id: 2, name: "sub2"},
            {id: 3, name: "sub3"}
        ]
    }]
}

Ответы [ 2 ]

0 голосов
/ 04 мая 2018
db.School.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $lookup: // Equality Match
            {
                from: "Faculty",
                localField: "id",
                foreignField: "schoolId",
                as: "faculties"
            }


        },

        // Stage 2
        {
            $unwind: {
                path: "$faculties",
                preserveNullAndEmptyArrays: false // optional
            }
        },

        // Stage 3
        {
            $lookup: // Equality Match
            {
                from: "Subject",
                localField: "faculties.id",
                foreignField: "facultyId",
                as: "faculties.subjects"
            }


        },

        // Stage 4
        {
            $group: {
                _id: {
                    id: '$id',
                    name: '$name'
                },
                faculties: {
                    $addToSet: '$faculties'
                }
            }
        },

        // Stage 5
        {
            $project: {
                id: '$_id.id',
                name: '$_id.name',
                faculties: 1
            }
        },

    ]



);
0 голосов
/ 04 мая 2018

Хорошо, спустя века я действительно нашел решение, которое намного проще, чем кроличья нора, которую я провалил.

{ $match: {id: 100001}},
{ $lookup:
    {
        from: 'faculties',
        localField: 'id',
        foreignField: 'schoolId',
        as: 'faculties',
    }
},
{ $unwind: {
    path: "$faculties",
    preserveNullAndEmptyArrays: true
  }
},
{ $lookup:
    {
        from: 'subjects',
        localField: 'faculties.id',
        foreignField: 'facultyId',
        as: 'faculties.subjects',
    }
}  

, который возвращает точный вывод, который я хотел. Ключом является окончательный поиск, возвращающий as: 'faculties.subjects', который ставит предметы на факультеты, что является первым ребенком в школах.

Если вам нужна дополнительная вложенность, вам нужно просто идти as: faculties.subjects.students.names, например, каждый раз, когда вы углубляетесь

...