skip to Main Content

If I have a controller like this:

const Review = require('../models/review')
const Launch = require('../models/launch')

async function getReviewsByUserId (req, res) {
  const { userId } = req.params

  const reviews = await Review.find({ userId }).lean() || []

  return res.status(200).send(reviews.reverse())
}

How can I use the returned reviews to query more objects in the fastest way possible? Example of what I mean:

async function getReviewsByUserId (req, res) {
  const { userId } = req.params

  const reviews = await Review.find({ userId }).lean() || []

  let launches = []
  for (review in reviews) {
    let launch = await Launch.find({launchId: review.launchId})
    launches.push(launch)
  }

  return res.status(200).send(launches.reverse())
}

So as you can see, I simply loop though all my reviews and then use the review.launchId to lookup launches and push each to an array and return that.

Is this efficient? Is there a faster way to accomplish the same thing?

2

Answers


  1. You can use the operator $in to find multiple elements by launchId.

    async function getReviewsByUserId (req, res) {
      const { userId } = req.params
    
      const reviews = await Review.find({ userId }).lean() || []
    
      let launches = []
      const reviewLaunchIds = reviews.map(review => review.launchId)
      let launch = await Launch.find({launchId:{ $in: reviewLaunchIds })
    
      return res.status(200).send(launch)
    }
    
    Login or Signup to reply.
  2. Using aggregate pipelines would be faster and more efficient but a little complicated to use.

    The query could be achieved by:

    async function getReviewsByUserId(req, res) {
      const { userId } = req.params;
    
      const launches = await Review.aggregate([
        {
          $match: {
            userId
          }
        },
        {
          $lookup: {
            from: "launches",
            localField: "launchId",
            foreignField: "launchId",
            as: "launches"
          }
        },
        {
          $unwind: {
            path: "$launches",
            preserveNullAndEmptyArrays: true
          }
        },
        { $group: { _id: "$launches._id", data: { $first: "$$ROOT" } } },
        { $replaceRoot: { newRoot: "$data.launches" } }
      ]);
    
      return res.status(200).send(launches.reverse());
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search