структура агрегации - добавить поле с вычисленным значением - PullRequest
0 голосов
/ 10 апреля 2020

Я довольно новичок в пн go и застрял в правильной агрегации моих данных. У меня есть две модели, Grant и User. Отношения между ними сохраняются внутри memberSchema в модели Гранта. Логика c заключается в том, что предоставление может иметь несколько пользователей, которые выделили определенное количество часов с соответствующим предоставлением. Ниже я опубликую Модели.

Модель пользователя

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    firstName: {type: String, required: true, trim: true, max: 50},
    lastName: {type: String, required: true, trim: true, max: 50},
    email: {type: String, required: true, max: 255, trim: true},
    password: {type: String, required: true, trim: true, min: 8, max: 1024},
    role: {type: String, default: 'basic', enum: ["basic", "supervisor", "admin"], trim: true},
    tokens: [{
        token: {
            type: String
        }
    }]
}, {
    timestamps: true,
    toObject: { virtuals: true },
    toJSON: { virtuals: true }
});

userSchema
.virtual('grants', {
    ref: 'Grant',
    localField: '_id',
    foreignField: 'members.member',
    justOne: false
});

module.exports = mongoose.model('User', userSchema);  

Модель гранта

const mongoose = require('mongoose');

const budgetSchema = new mongoose.Schema({
    year: {type: Number, required: true, trim: true},
    money: {type: Number, required: true, trim: true}
}, { timestamps: true });

const memberSchema = new mongoose.Schema({
    member: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true
    }, 
    hours: {type: Number, required: true},
    active: {type: Boolean, default: true},
    role: {type: String, default: 'basic', enum: ["basic", "deputy", "leader"]}
}, { timestamps: true });

const grantSchema = new mongoose.Schema({
    name: {type: String, required: true, trim: true, max: 100},
    idNumber: {type: String, required: true, trim: true, max: 100},
    type: {type: String, enum: ["APVV", "VEGA", "KEGA"], trim: true, required: true
    },
    start: {type: Date, default: Date.now},
    end: {type: Date, required: true},
    budget: [budgetSchema],
    members: [memberSchema]
}, {
    timestamps: true,
    toObject: {virtuals: true},
    toJson: {virtuals: true}
});

grantSchema
.virtual('url')
.get(function () {
    return '/api/grant/' + this._id;
})

module.exports = mongoose.model('Grant', grantSchema);

Теперь, используя виртуальное заполнение, я могу вернуть список пользователей с соответствующими грантами. (и их члены), используя этот запрос:

const users = await User.find().populate({path: 'grants', populate:{path: 'members.member'}}); 

Моя проблема в том, что я хотел бы вернуть тот же список пользовательских объектов, но с добавленным дополнительным полем для каждого пользовательского объекта с суммой всех часов распределяется по всем грантам, которым назначен данный пользователь. Я подумал, что могу выполнить 1015 * с помощью структуры агрегации, но не могу понять, как это сделать. Любая помощь с некоторыми объяснениями будет высоко ценится!

...