Best way to retrieve a reference field using $lookup in Mongoose?

Viewed 707

I have two models Book and Author, Book has reference of Author, suppose an Author got deleted then I only want to retrieve those Books who have an author:

BookSchema with these fields

name: String,
author: {
  type: Schema.Types.ObjectId,
  ref: 'Author',
  required: [true, 'A book must have an author']
}

AuthorSchema with these fields

name: String

I have to do it using $lookup operator. I am able to get the desired result but I don't know if it's a good way. This is my solution:

const books = await Book.aggregate([
      {   $lookup: {
          from: 'authors',
          localField: 'author',
          foreignField: '_id',
          as: 'bookAuthor'
          }
      },
      {   $match: {   bookAuthor: { $not: { $size: 0 } }   }   },
      {   $unwind: '$bookAuthor'   },
      {   $project: {
          name: 1,
          bookAuthor: {   name: 1   }
          }
      }
    ]);
1 Answers

You have done everything correct, but you don't need to use the $match in second phase of aggregation pipeline. $unwind will automatically remove the documents with empty bookAuthor array, so if there is no author, it will be removed after $unwind stage.

Try this:

const books = await Book.aggregate([
  {   $lookup: {
      from: 'authors',
      localField: 'author',
      foreignField: '_id',
      as: 'bookAuthor'
      }
  },
  {   $unwind: '$bookAuthor'   },
  {   $project: {
      name: 1,
      bookAuthor: {   name: 1   }
      }
  }
]);

Have a look at this Mongo Playground to see it working

Related