Instructor: Let's now populate the reviews
with both the user and the tour data.
So just like the did on the tour, let's now make is so
that both the tour and the user will be automatically
populated each time there is a query for a review.
Since we already did that before, I will now
give you yet another challenge, okay.
So I want you to go ahead and do it
just like we did in the tours, but now for the reviews.
Just a hint that I need to give you
before you can do this on your own,
is that when you want to populate two fields,
you need to actually call populate twice.
So once for each of the fields, all right.
With that information, you should be good to go
to pause the video now and go and try it.
So I hope that wasn't too hard.
Let's go ahead and just close some files here,
so everything that's not related to reviews,
we don't need anymore.
So let's just go to the review model and then
implement, or pre-find middleware.
So we do that on the schema, as you already know,
and then again we use a regular expression
to basically match strings, which start with find.
So again, this is going to work for find,
for find one, and all the other find one methods
that are available in Mongoose.
As always, I start by writing next.
And now really all we need to do
is to call populate on the current query, so this.populate,
and I will now actually specify the options object
because I only want to select a couple of fields
and not the entire tour, and also not the entire user.
So remember, we start with the path property,
and this one is going to be for tour.
So again, by specifying tour here, means that
this field here, which has the exact some name,
is then going to be the one that's populated
based on a tour model.
Well, because that's what we specified here, okay.
So the reference is to a model called tour,
and basically it's in that collection where Mongoose is then
going to look for documents with the ID that we specified.
All right, so we want a tour, but then
let's say that we actually only want
the tour name and nothing else.
So select, okay, and then just the name,
and then as I said, if we want to populate multiple fields,
well all we need to do is to call populate again.
So at this point the query is populated with the tours,
and now we need to populate it again,
this time with the user.
And now select, and that's actually
only display the user name and the photo,
and not for example, stuff like the email.
So let's say that someone hits
the API to get all the reviews,
but then we don't want to leak all the details
about the users posting these reviews to the client.
So no one should really be able to know the private data
about the reviewers, like emails, okay.
So again, we only leak, we only send relevant data about the
user, and in this case, it's the name and the photo, okay.
So give this a save, and if we now
hit or get all reviews endpoint,
well then already the tour and the user should be populated
instead of us just seeing the IDs there.
Let's try that, and here we go.
So that's working, we get the name,
and of course also the ID, and then the same for the user.
So we get the name, but then not the photo.
So let's see, maybe I didn't get, specify
the photo property, so let's take a look at that.
So the userModel, but actually it is there.
No, I'm sorry, of course we do not see the photo
because we never specified any photo for any of our users.
Okay, and therefore the only property that actually exists
is the name, and so that's what we then get.
Okay, and that's actually it.
So really simple, that's all we need to do
to get all the related data,
and just as we specified in our data model.
Now again, just keep in mind
that this one is going to add some extra queries,
and in this case, it's actually two queries,
because behind the scenes, Mongoose will actually
have to query both the tours and also the users
in order to find the matching document, okay.
So this should then probably
add some time here to the query.
So it took 266 milliseconds, like this.
Let's just, for the sake of experiment,
comment out this code, and then try it again.
And this is taking a lot of time, I'm not sure why.
So let's do it again, and so you see, 157 milliseconds,
and if we now put it back, let's do it again.
And again, it takes a lot of time,
and so again, I'm doing it twice.
But still you see that it took a little bit longer, okay.
So not the end of the world,
it was just like 100 milliseconds more,
but when you reach a certain scale,
that might make a difference.
So again, I just want you to keep that in mind.
Anyway, that's it for this lecture, so let's now move on.