У меня есть 2 модели в Mongoose (с использованием NodeJS): Post и User
//User Schema > User.model.js
const UserSchema = new Schema({
email: String,
premium: Boolean
});
module.exports = model('User', UserSchema);
// Post Schema > Post.model.js
const PostSchema = new Schema({
title: String,
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
}
});
module.exports = model('Post', PostSchema)
Учитывая эти модели, в моем getPosts controller
я хочу вернуть только posts
в зависимости от свойства premium
пользователя этого post
.
Например:
const docs = await Post.find({ 'user.premium': false })
Я понимаю, что не могу получить доступ к свойству premium
, потому что оно просто не существует, пока не завершится метод find (). Значение true
или false
для user.premium
взято из query params
.
Чтобы добиваться консультации в 1 одинокой peticiГіn в базу данных, ты можешь использовать один mГ©todo agregaciГіn .
В этом случае процесс agregaciГіn потребует они следующий этапов:
users
используя один lookup
с нее colecciГіn posts
. lookup
возвращает один array
с объектами, которые совпадают, поэтому необходимо доставать тех же самых как поле, отличное от одного array
. Чтобы этого добиваться мы используем $unwind
, которые отделяют документы в количестве документов, которое содержит array
. Ввиду того, что sГіlo имеется документ, просто reemplazarГЎ array
из-за объекта. user.premium
, и сможем сходить за стоимость parГЎmetro полученный в req.parmas
. , Чтобы использовать ее agregaciГіn в Mongoose, мы используем mГ©todo aggregate()
из модели, следующей формы:
// El modelo aobre el que aplicaremos el metodo aggregate es Post
postAggregate = Post.agregate([
{
// etapa $lookup
$lookup:
{
from: 'users', // <- nombre de la colección de donde se extrae la data
localField: 'user', // <- nombre del campo local (post.user) que tiene la referencia a users
foreignField: '_id', // <- nombre del campo de la colección users al que se hace la referencia
as: 'user' // <- nombre del campo que almacenará el resultado (se sobreescribe post.user)
}
},
// etapa $unwind
{
$unwind: '$user' // <- nombre del campo que contiene el array de objetos
},
// etapa $match
{
$match: {
'user.premium': req.params.premium // <- condición que se evaluará para filtrar el resultado
}
}
}
]);
Сейчас только достаточно использовать mГ©todo exec()
из тебя agregaciГіn, чтобы получать результат:
const docs = await postAggregate.exec(); // <- ejecuta la consulta
AsГ, - тебе удается реализовать выданного, в котором ты нуждаешься используя единственную консультацию в BD, позволяя, чтобы механизм той же самой реализовал задание выданный.
Помнит что использует блоки try catch
, когда ты работаешь с async/await
, Я надеюсь, что это помогает тебе решать проблему.