Node and Mongoose: как искать документы и фильтровать их по свойствам ссылочного объекта?

У меня есть 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.

1115] Я хочу знать, есть ли способ достичь этого. Спасибо, и я надеюсь, что вы можете помочь мне.

0
задан 26.10.2019, 15:30
1 ответ

Чтобы добиваться консультации в 1 одинокой peticiГіn в базу данных, ты можешь использовать один mГ©todo agregaciГіn .

В этом случае процесс agregaciГіn потребует они следующий этапов:

  1. $lookup : Он позволяет нам реализовывать консультации, не соотнесенные между двумя коллекциями. В этом случае мы будем извлекать данные о ней colecciГіn users используя один lookup с нее colecciГіn posts.
  2. $unwind : Результат этапа lookup возвращает один array с объектами, которые совпадают, поэтому необходимо доставать тех же самых как поле, отличное от одного array. Чтобы этого добиваться мы используем $unwind, которые отделяют документы в количестве документов, которое содержит array. Ввиду того, что sГіlo имеется документ, просто reemplazarГЎ array из-за объекта.
  3. $match : В этом этапе мы выдадим документы посредством поля 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

, Я надеюсь, что это помогает тебе решать проблему.

0
ответ дан 10.11.2019, 23:14
  • 1
    Твой вклад правда в том, что он гениален! Ты объяснил мне жизнь! Спасибо!! – Manuel Pascual 11.11.2019, 23:30

Теги

Похожие вопросы