Michael Torres
Michael Torres

Reputation: 512

How to get object in deeply nested array in mongoose using nodes

In my collection of users I have the following

{
  _id: ObjectId('whatever user id'),
  movies: [
    {
      _id: ObjectId('whatever id of this movie'),
      name: 'name of this movie',
      actors: [
        {
          _id: ObjectId('whatever id of this actor'),
          name: 'name of this actor'
        }
      ]
    }
  ]
}

So in my users collection I want to be able to query for a actor by the user.id, pet.id, and the actor.id

I want to return the actor somewhat like this...

actor: {
  fields...
}

I tried the following...

const actor = await User.findById(req.user.id, {
  movies: {
    $elemMatch: {
      _id: req.params.movie_id,
      actors: {
        $elemMatch: {
          _id: req.params.actor_id,
        },
      },
    },
  },
});

I have tried other things but can't seem to get it to work. I saw that you can maybe use aggregate but I am not sure how to query that while using the ids I have at my disposal.

Upvotes: 2

Views: 516

Answers (1)

Michael Torres
Michael Torres

Reputation: 512

I was able to figure it out by using aggregate. I was using this before but it seems that I needed to cast my ids with mongoose.Types.ObjectId so a simple req.user.id would not work.

In order to get my answer I did...

const user = await User.aggregate([
  { $match: { _id: mongoose.Types.ObjectId(req.user.id) } },
  { $unwind: '$movies' },
  { $match: { 'movies._id': mongoose.Types.ObjectId(req.params.movie_id) } },
  { $unwind: '$movies.actors' },
  {
    $match: {
      'movies.actors._id': mongoose.Types.ObjectId(req.params.actor_id),
    },
  },
]);

This did not return data in the following format...

actor: {
  fields...
}

but returns it instead like this...

user: {
  movies: {
    actor: {
      fields...
    }
  },
  otherFields...
}

then sending the response back...

res.status(200).json({
  status: 'success',
  data: {
    actor
  }
})

gives that format I wanted. However, I would still want to know how to just get the data actor without getting the full document

Upvotes: 2

Related Questions