Как заполнить и сгруппировать вложенные документы внутри вложенных документов в одном запросе агрегации? - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть эти 3 схемы: Платеж, Программа и Подписка.

const paymentSchema = new Schema({
    toUser: {type:Schema.Types.ObjectId, ref: 'User'},
    subscription: {type:Schema.Types.ObjectId, ref: 'Subscription', default: null }
});

const subscriptionSchema = new Schema({
    user: {type:Schema.Types.ObjectId, ref: 'User'}, // user who is subscribed to program
    program: {type:Schema.Types.ObjectId, ref: 'Program'}
});

const Program = new Schema({
            title: { type: String, required: true, max: [50, 'Too long, max is 50 characters']},
            country: { type: String, required: true },
            //Some more properties...
            //...
            category: { type: String, required: true, lowercase: true },
);

Я хочу получить все платежи, в которых зарегистрированный пользователь соответствует свойству "toUser", заполнить подписку внутри платежа, затем заполнить программувнутри подписки и, наконец, группа по программе.Звучит странно, но конвейер будет выглядеть примерно так:

(Получить платежи toUser) => (заполнить Payment.subscription) => (заполнить Payment.subscription.program) => (сгруппировать по платежам.subscription.program)

Однако я не понимаю, как этого добиться, используя агрегацию, поскольку платеж содержит только ссылку на «Подписку», а «Подписка» содержит ссылку на «Программу»

Я пытался сделать что-то вроде этого, где я каждый раз дважды ищу соответствующий поддокумент

const groupedPayments = await Payment.aggregate([
        {$match: {$and: [{"toUser": user._id},{"booking": null}]}},
        {$lookup:
            {
                from: "subscription",
                localField: "subscription",
                foreignField: "id",
                as: "subscriptions"
            }
        },
        {$lookup:
            {
                from: "program",
                localField: "program",
                foreignField: "id",
                as: "program"
            }
        },
        {$group: {_id: "$subscription.program"}}
    ])

Я хочу получить все свои данные в формате, похожем на этот:

{ "_id" : { "program" : "Title 1"}, 
  "payments" : [
        { "payment_1": {//some data//},
        { "payment_2": {//some data//},
        { "payment_X": {//some data//}
    ]
},
{ "_id" : { "program" : "Title 2"}, 
  "payments" : [
        { "payment_1": {//some data//},
        { "payment_2": {//some data//},
        { "payment_X": {//some data//}
    ]
},
{ "_id" : { "program" : "Title 3"}, 
  "payments" : [
        { "payment_1": {//some data//},
        { "payment_2": {//some data//},
        { "payment_X": {//some data//}
    ]
},
...