In this video you're going to learn how to read documents from your Mongo DB database.
This is going to bring us from C a four create to R for Reid.
We're gonna be able to read individual documents by I.D. or by any other field and we're also gonna
be able to fetch multiple documents limiting them to a specific subset like users whose age is twenty
seven or tasks that have yet to be completed before we get started.
Let's go ahead and remove these three lines related to the object I.D..
Remember all of the stuff covered previously is always available in the PDA guide and you could always
choose to leave that code around if you wanted to.
And down below I'm going to remove all of the code we have in that callback for our 4 calls to insert
one and insert many that's gonna leave us with an empty connect function we can use to explore how we
can fetch data out of the database.
Once again documentation for insert and insert many can also be found in a PD f guide for the class.
So when it comes to fetching data out of the database there are two main methods we're gonna use.
We can view both over in the documentation for collection.
This is the same area where we found the insertion methods.
We are looking for find and find one find is going to allow us to fetch multiple documents out of the
database such as people who are twenty seven and find one is going to allow us to fetch an individual
document.
Now there are other methods that start with find but those are all related to other things like find
and modify or changing the document or find and remove for removing a document and we'll talk about
updating and deleting data a bit later.
For now the focus is on find and find one.
So let's go ahead and start the process of fetching some data out of the database and we'll start with
find one to find an individual document.
Let's pull up our users collection and pick a user we want to fetch.
I'm gonna fetch this one right here with the name equal to Jen.
So let's go ahead and do just that by first specifying the collection we're trying to use find one on.
So D.B. dot collection.
Right here we pass in the string users like we had before when we were using insert one and insert many
and then right here we're gonna use find one now find one accepts two required arguments.
The first is an object and the second is a function.
So the object is used to specify our search criteria if we want to search for a user by their name.
We specify a name field on this query object and we provide the value we're looking for.
In this case capital J.
Jenn is the name we're searching for.
Now the callback gets called when the operation is complete and we either get back an error or we get
back the actual document.
So I could call this user which would be an appropriate name though you could call it whatever you like
to since it's just a function argument down below.
We can now do something with the response.
First up if there was an error we can go ahead and handle it by returning using console dot log some
sort of message unable to fetch and then down below we can actually dump the user to the console to
view that document.
So console dot lug printing user to the screen.
So with this in place I would expect that we're able to find our one document since there is a user
with the name of Gen.
Let's go ahead and save the program and run the script from the terminal that's node Mongo D.B. dot
J s when I run it what do I get right here.
I can see my one document printing.
I have Jen's idea I have the name for Jan and I have the age 28 all matches up with the data stored
in the database.
Now in this case we're just searching by one field name.
We could also choose to search by more fields by specifying those on the list.
Now what happens if we do search for something else like age but we provide an age that would return
no results like one for example there is no Gen inside of our database with the age of 1.
Now what's going to happen is not an error.
This is still a completely valid operation.
If we save the program we can rerun things to see what we get down below.
What do we get we get.
No.
So searching for a document and not finding one is not an error.
Everything did go well.
We gave you back what you asked for.
There was just nothing to give back.
It was able to correctly communicate with the database though and go through the process of searching
for what you were looking for.
Now find one always returns just a single document.
If your query matches multiple documents it's just going to grab the first one.
So for example there are two users with the name of Andrew.
It's always going to return this first document.
If we just searched for name Andrew and we have three users who have the age of twenty seven we're always
going to get the first one back.
Now if we wanted to search for a specific document we could always do that by its unique identifier.
So let's go ahead and do that before moving on to find.
To search for multiple documents right here we're gonna go ahead and grab an I.D. for one of our documents
you can pick any one you like.
I'm gonna grab the I.D. for Vikram to grab the I.D. text.
We can just right click click edit document and we can grab right here what's inside of quotes.
So I'm going to copy that to the clipboard.
Click cancel and I'm gonna bring that over to Mongo DB dot J.
S right here.
We can now swap out what we have inside of the query object instead of searching by name and age.
I'm just going to search by I.D. Now it's not enough to provide a string I.D. so I can't just open and
close a set of quotes and paste that I.D. in.
Remember in the last video we learned that was actually stored is an object I.D. It's not a string it
is binary data.
So this search is going to return no results and it's a common error.
So I do want to save it run it just to prove the point right here.
File is saved.
I will execute the program once again and we do not get any results back.
If we want to search by I.D. We have to provide an object I.D..
So we have to use that function and we talked about earlier right here.
Let's go ahead and wrap this string in that function call.
I'm going to cut this string out including the opening and closing quotes.
I'll use new object I.D. then I'm going to pass to it the string that I just cut out.
Now we are providing a valid object I.D..
Any query object.
And if we rerun the program we are indeed going to get the result expected.
So right here I can see that we do have the document showing up for Vikram.
Now you might be saying hey that's a lot of extra work.
Why can't that just be done for us a little bit later in the course we will learn how we can avoid calling
new object I.D. but for now that's the standard way to get things done when using the Mongo D.B. native
driver.
Now finding one document is a good start.
We can also use find to find multiple documents so we could search for users by name or age or we could
search for tasks by any criteria like whether or not it's been completed.
Let's go ahead and set up a call to find that's D.B. dot collection.
We're going to search in users once again and we'll try to find users who have the age of 27 and we
know we have three users that fit that criteria.
And we're gonna go ahead and call find to pass our query object in just like we did for find one.
Now it doesn't make sense to search by I.D. when using Find since you would only ever get a single record
back since the I.D. is unique.
So typically when using find we're searching by a different field on the document.
In this case I'm going to find users whose age has a value of twenty seven once again and that would
return three documents.
Now find is a bit different then find one insert one or insert many.
And that's because find it doesn't take in a callback as that second argument with find what we get
back as the return value is actually a cursor and the cursor is not the data you've asked for.
It is a pointer to that data in the database.
And the reason we're getting a cursor back is Mongo D.B. isn't going to assume that every time you use
find you always want to get back an array of all of those documents.
There are a lot of other things you might want to do like get just the first five documents or do something
even different like just get the number of matching documents.
You don't even want any document data themselves.
So when we get a cursor back it opens up a lot more possibilities.
Now we can explore all of this by heading over to the documentation.
So if we go over to Google Chrome and we scroll down to our f methods for collection we have find one
right here.
We pass in the query which we did.
We have our optional options which we did not specify and then down below we add the callback which
we did specify if we go over to find though we can see that we still have the query and those optional
options.
But there is no callback as a third argument.
Now we can see that we also get a return value right here of cursor and when we click that it's going
to bring us over to something else in the docs.
If we scroll down we have cursor sitting right here.
So what we get back from find is indeed a cursor it is a pointer to data.
There are all sorts of methods we can use with it.
We can use things to limit the data like limit I can count the data up with count I can do other forms
of aggregation or I can use one of the more popular methods to array to array is going to allow us to
get back an array of documents which in this case is exactly what we want.
So over here.
What does that mean for us.
It means that finder returns a cursor and the cursor has a 2 array method.
So right here I'm going to call to array now to array.
That is what takes the callback function where we either get the error or we get our matching documents.
In this case we could call them users.
Now let's go ahead and dump those to the council to see what we get since the error handling is going
to be the same either way.
I'm just going to temporarily ignore that.
I'll use console log to just dump users to the console.
We can save Mongo DB and test things out.
Now I will comment out my call to find one just to clean up the output we see in the terminal down below
and I'll restart the script I'll shut it down.
Start it up once again and right here.
What am I getting.
I'm getting an array of three documents back where each document has an age of twenty seven.
So using this simple call I was able to fetch multiple pieces of data from the database limiting them
by some criteria.
Now to further explain why cursors are being used we can take this call copy it and duplicate it down
below.
We're gonna switch from using the to array cursor method over to using count.
Now count still takes in a callback and we get an error potentially or the count.
So right here I can just call that count.
Then I'll just print count to the console.
So it's very similar to what we had above with a few minor changes.
Now if we rerun the program we can see the output we're gonna get.
So right here I get my array for that first call to find and for the second I get the number three.
So this is the advantage of the cursor.
Sometimes I want to get the data I want to get all of the individual fields back and in that case to
array gets the job done.
But if I do want to do something simple like count there's no need to fetch all of those records store
them in memory in node j s only to get a single number back.
Mongo DB can handle that for us instead of needing to transfer all of the documents across the network.
It can just transfer that single integer.
In this case the number three.
So the cursor is a nice tool for us to be able to use and hopefully this example illustrates why we
might not always want to get all of the data back.
While we might want to sometimes do something a little bit different now it is challenge time where
you're going to use our search methods find one and find to find documents in the tasks collection and
right here.
I have some challenge comments right here.
Your challenge is to use find and find one with the tasks collection.
So step one you're gonna use find one to fetch the latest task in that collection by its I.D. and you'll
print that document to the console then you're going to use a call to find to attach all tasks that
are not completed and you're going to print those to the console as well.
Finally you're going to test your work.
So when you run the script you should see one document print.
The last task then the next thing that prints should be an array of documents all of the tasks that
have not been completed.
Take some time to knock that out using the code disgust up above.
Test your work and when you're done come back and click play
how would you do.
Let's go ahead and kick things off by pulling up the tasks collection and robo 3D so we can see the
data.
We're working with.
I have that sitting right here.
Now the first thing was to grab the document the last one and buy I.D..
So I'm gonna edit that document just so I can copy it to the clipboard easily.
I'll close the editor and I'll bring that over to mongo.
Dot J S right here.
D.B. dot collection since we are trying to access the tasks collection and right here I'm gonna use
find one to find a document by its I.D. so any query object we're searching by I.D. and I'm searching
by an object I.D. So I use new object I.D. passing in inside of quotes the object I.D. value.
Now from there we provide that second argument which is our callback function we get a potential error
and we potentially get the document which I'll call a task.
Right here we can go ahead and provide the arrow function body and in here all I'm gonna do is dump
task to the console.
So console dot plug printing task.
Now we can go ahead and test our work one step at a time.
So right here I'll go ahead and rerun things I'll shut the program down.
Start it up once again and I am indeed seeing that last task with a description of pot plants and a
completed value of false which matches up with what I have over here.
Next up step two was to find all of the documents that have not been completed.
So right here for that we'll use D.B. dot collection.
Once again we're looking in tasks and we're using find to find documents where it completed is equal
to False.
Now from here we can't just provide a callback function since remember bind returns a cursor.
Now we could use other cursor methods to do other things.
In this case though we do indeed want to print all of those documents.
So I'll use to array when we use to array.
It actually goes off to the server and fetches all of those documents.
Right here we either have an error or we have our list of tasks.
Perfect.
Let's go ahead and print them console dialogue printing tasks.
Now we're gonna go ahead and run our program for the final time.
Down below I'll shut down the script.
I'll start it up again.
We have as the first piece of output our last item which was fetched by I.D..
Then we have our array with all of the documents all of the tasks that have not been completed.
I have renew inspection and I have pot plants both which indeed have a completed value of false.
I'm not seeing clean the house show up anywhere.
Since that has already been completed.
Now this example query is the kind of query you would use if you're trying to show someone all of these
things they still need to do.
Now that we know how to find our documents we have knocked out both C for create and R for read down
below.
I'm also going to remove the challenge comments since we're all done with that one.
Now we do still have to cover you for update and D for delete but before we do we're going to take a
quick break to talk about a very important asynchronous tool at our disposal.
This is the promise and we're going to start talking about it in the next video.
So let's go ahead and jump right in.