1 00:00:00,210 --> 00:00:05,400 In this video you're going to learn how to read documents from your Mongo DB database. 2 00:00:05,400 --> 00:00:10,580 This is going to bring us from C a four create to R for Reid. 3 00:00:10,650 --> 00:00:16,900 We're gonna be able to read individual documents by I.D. or by any other field and we're also gonna 4 00:00:16,920 --> 00:00:23,970 be able to fetch multiple documents limiting them to a specific subset like users whose age is twenty 5 00:00:23,970 --> 00:00:29,190 seven or tasks that have yet to be completed before we get started. 6 00:00:29,220 --> 00:00:33,600 Let's go ahead and remove these three lines related to the object I.D.. 7 00:00:33,810 --> 00:00:39,540 Remember all of the stuff covered previously is always available in the PDA guide and you could always 8 00:00:39,540 --> 00:00:42,910 choose to leave that code around if you wanted to. 9 00:00:42,960 --> 00:00:49,740 And down below I'm going to remove all of the code we have in that callback for our 4 calls to insert 10 00:00:49,830 --> 00:00:55,890 one and insert many that's gonna leave us with an empty connect function we can use to explore how we 11 00:00:55,890 --> 00:00:57,860 can fetch data out of the database. 12 00:00:57,870 --> 00:01:05,310 Once again documentation for insert and insert many can also be found in a PD f guide for the class. 13 00:01:05,310 --> 00:01:10,420 So when it comes to fetching data out of the database there are two main methods we're gonna use. 14 00:01:10,500 --> 00:01:14,260 We can view both over in the documentation for collection. 15 00:01:14,280 --> 00:01:18,160 This is the same area where we found the insertion methods. 16 00:01:18,230 --> 00:01:25,620 We are looking for find and find one find is going to allow us to fetch multiple documents out of the 17 00:01:25,620 --> 00:01:31,650 database such as people who are twenty seven and find one is going to allow us to fetch an individual 18 00:01:31,680 --> 00:01:32,810 document. 19 00:01:32,820 --> 00:01:38,340 Now there are other methods that start with find but those are all related to other things like find 20 00:01:38,340 --> 00:01:44,700 and modify or changing the document or find and remove for removing a document and we'll talk about 21 00:01:44,760 --> 00:01:47,310 updating and deleting data a bit later. 22 00:01:47,310 --> 00:01:50,460 For now the focus is on find and find one. 23 00:01:50,820 --> 00:01:56,310 So let's go ahead and start the process of fetching some data out of the database and we'll start with 24 00:01:56,310 --> 00:01:59,250 find one to find an individual document. 25 00:01:59,370 --> 00:02:03,210 Let's pull up our users collection and pick a user we want to fetch. 26 00:02:03,210 --> 00:02:07,210 I'm gonna fetch this one right here with the name equal to Jen. 27 00:02:07,290 --> 00:02:13,260 So let's go ahead and do just that by first specifying the collection we're trying to use find one on. 28 00:02:13,590 --> 00:02:17,050 So D.B. dot collection. 29 00:02:17,050 --> 00:02:23,050 Right here we pass in the string users like we had before when we were using insert one and insert many 30 00:02:23,710 --> 00:02:29,830 and then right here we're gonna use find one now find one accepts two required arguments. 31 00:02:29,830 --> 00:02:33,970 The first is an object and the second is a function. 32 00:02:33,970 --> 00:02:41,590 So the object is used to specify our search criteria if we want to search for a user by their name. 33 00:02:41,590 --> 00:02:47,390 We specify a name field on this query object and we provide the value we're looking for. 34 00:02:47,530 --> 00:02:49,190 In this case capital J. 35 00:02:49,210 --> 00:02:52,090 Jenn is the name we're searching for. 36 00:02:52,090 --> 00:02:58,000 Now the callback gets called when the operation is complete and we either get back an error or we get 37 00:02:58,000 --> 00:03:00,070 back the actual document. 38 00:03:00,070 --> 00:03:05,040 So I could call this user which would be an appropriate name though you could call it whatever you like 39 00:03:05,040 --> 00:03:08,230 to since it's just a function argument down below. 40 00:03:08,230 --> 00:03:10,450 We can now do something with the response. 41 00:03:10,450 --> 00:03:17,170 First up if there was an error we can go ahead and handle it by returning using console dot log some 42 00:03:17,170 --> 00:03:24,730 sort of message unable to fetch and then down below we can actually dump the user to the console to 43 00:03:24,730 --> 00:03:26,470 view that document. 44 00:03:26,470 --> 00:03:30,730 So console dot lug printing user to the screen. 45 00:03:30,730 --> 00:03:36,190 So with this in place I would expect that we're able to find our one document since there is a user 46 00:03:36,370 --> 00:03:37,790 with the name of Gen. 47 00:03:37,840 --> 00:03:43,380 Let's go ahead and save the program and run the script from the terminal that's node Mongo D.B. dot 48 00:03:43,390 --> 00:03:46,720 J s when I run it what do I get right here. 49 00:03:46,780 --> 00:03:48,680 I can see my one document printing. 50 00:03:48,700 --> 00:03:56,050 I have Jen's idea I have the name for Jan and I have the age 28 all matches up with the data stored 51 00:03:56,080 --> 00:03:57,710 in the database. 52 00:03:57,730 --> 00:04:01,020 Now in this case we're just searching by one field name. 53 00:04:01,120 --> 00:04:06,540 We could also choose to search by more fields by specifying those on the list. 54 00:04:06,540 --> 00:04:13,210 Now what happens if we do search for something else like age but we provide an age that would return 55 00:04:13,270 --> 00:04:20,300 no results like one for example there is no Gen inside of our database with the age of 1. 56 00:04:20,440 --> 00:04:23,200 Now what's going to happen is not an error. 57 00:04:23,200 --> 00:04:26,230 This is still a completely valid operation. 58 00:04:26,230 --> 00:04:30,380 If we save the program we can rerun things to see what we get down below. 59 00:04:30,400 --> 00:04:31,770 What do we get we get. 60 00:04:31,810 --> 00:04:32,690 No. 61 00:04:32,770 --> 00:04:36,910 So searching for a document and not finding one is not an error. 62 00:04:36,910 --> 00:04:38,340 Everything did go well. 63 00:04:38,500 --> 00:04:40,640 We gave you back what you asked for. 64 00:04:40,660 --> 00:04:42,790 There was just nothing to give back. 65 00:04:42,820 --> 00:04:48,040 It was able to correctly communicate with the database though and go through the process of searching 66 00:04:48,040 --> 00:04:49,630 for what you were looking for. 67 00:04:49,630 --> 00:04:52,660 Now find one always returns just a single document. 68 00:04:52,660 --> 00:04:56,770 If your query matches multiple documents it's just going to grab the first one. 69 00:04:56,770 --> 00:05:00,340 So for example there are two users with the name of Andrew. 70 00:05:00,490 --> 00:05:03,230 It's always going to return this first document. 71 00:05:03,280 --> 00:05:09,610 If we just searched for name Andrew and we have three users who have the age of twenty seven we're always 72 00:05:09,610 --> 00:05:12,010 going to get the first one back. 73 00:05:12,040 --> 00:05:17,680 Now if we wanted to search for a specific document we could always do that by its unique identifier. 74 00:05:17,680 --> 00:05:21,100 So let's go ahead and do that before moving on to find. 75 00:05:21,100 --> 00:05:26,940 To search for multiple documents right here we're gonna go ahead and grab an I.D. for one of our documents 76 00:05:26,950 --> 00:05:28,630 you can pick any one you like. 77 00:05:28,630 --> 00:05:32,540 I'm gonna grab the I.D. for Vikram to grab the I.D. text. 78 00:05:32,560 --> 00:05:38,930 We can just right click click edit document and we can grab right here what's inside of quotes. 79 00:05:39,010 --> 00:05:41,150 So I'm going to copy that to the clipboard. 80 00:05:41,470 --> 00:05:45,450 Click cancel and I'm gonna bring that over to Mongo DB dot J. 81 00:05:45,470 --> 00:05:46,900 S right here. 82 00:05:46,900 --> 00:05:53,170 We can now swap out what we have inside of the query object instead of searching by name and age. 83 00:05:53,170 --> 00:06:00,040 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 84 00:06:00,040 --> 00:06:03,330 close a set of quotes and paste that I.D. in. 85 00:06:03,370 --> 00:06:09,550 Remember in the last video we learned that was actually stored is an object I.D. It's not a string it 86 00:06:09,550 --> 00:06:11,120 is binary data. 87 00:06:11,140 --> 00:06:15,730 So this search is going to return no results and it's a common error. 88 00:06:15,760 --> 00:06:19,990 So I do want to save it run it just to prove the point right here. 89 00:06:19,990 --> 00:06:21,150 File is saved. 90 00:06:21,250 --> 00:06:26,080 I will execute the program once again and we do not get any results back. 91 00:06:26,080 --> 00:06:30,460 If we want to search by I.D. We have to provide an object I.D.. 92 00:06:30,610 --> 00:06:34,510 So we have to use that function and we talked about earlier right here. 93 00:06:34,510 --> 00:06:38,770 Let's go ahead and wrap this string in that function call. 94 00:06:38,830 --> 00:06:42,920 I'm going to cut this string out including the opening and closing quotes. 95 00:06:43,120 --> 00:06:49,860 I'll use new object I.D. then I'm going to pass to it the string that I just cut out. 96 00:06:49,930 --> 00:06:53,050 Now we are providing a valid object I.D.. 97 00:06:53,140 --> 00:06:54,580 Any query object. 98 00:06:54,580 --> 00:06:58,900 And if we rerun the program we are indeed going to get the result expected. 99 00:06:58,900 --> 00:07:03,990 So right here I can see that we do have the document showing up for Vikram. 100 00:07:04,000 --> 00:07:06,670 Now you might be saying hey that's a lot of extra work. 101 00:07:06,670 --> 00:07:11,980 Why can't that just be done for us a little bit later in the course we will learn how we can avoid calling 102 00:07:11,980 --> 00:07:19,070 new object I.D. but for now that's the standard way to get things done when using the Mongo D.B. native 103 00:07:19,070 --> 00:07:20,010 driver. 104 00:07:20,240 --> 00:07:22,460 Now finding one document is a good start. 105 00:07:22,460 --> 00:07:30,050 We can also use find to find multiple documents so we could search for users by name or age or we could 106 00:07:30,050 --> 00:07:34,670 search for tasks by any criteria like whether or not it's been completed. 107 00:07:34,670 --> 00:07:40,520 Let's go ahead and set up a call to find that's D.B. dot collection. 108 00:07:40,520 --> 00:07:46,070 We're going to search in users once again and we'll try to find users who have the age of 27 and we 109 00:07:46,070 --> 00:07:48,980 know we have three users that fit that criteria. 110 00:07:49,190 --> 00:07:55,500 And we're gonna go ahead and call find to pass our query object in just like we did for find one. 111 00:07:55,550 --> 00:08:01,040 Now it doesn't make sense to search by I.D. when using Find since you would only ever get a single record 112 00:08:01,040 --> 00:08:03,270 back since the I.D. is unique. 113 00:08:03,350 --> 00:08:08,330 So typically when using find we're searching by a different field on the document. 114 00:08:08,330 --> 00:08:13,880 In this case I'm going to find users whose age has a value of twenty seven once again and that would 115 00:08:13,880 --> 00:08:15,680 return three documents. 116 00:08:15,680 --> 00:08:20,530 Now find is a bit different then find one insert one or insert many. 117 00:08:20,540 --> 00:08:26,840 And that's because find it doesn't take in a callback as that second argument with find what we get 118 00:08:26,840 --> 00:08:34,260 back as the return value is actually a cursor and the cursor is not the data you've asked for. 119 00:08:34,370 --> 00:08:37,730 It is a pointer to that data in the database. 120 00:08:37,820 --> 00:08:43,820 And the reason we're getting a cursor back is Mongo D.B. isn't going to assume that every time you use 121 00:08:43,820 --> 00:08:47,920 find you always want to get back an array of all of those documents. 122 00:08:47,930 --> 00:08:53,990 There are a lot of other things you might want to do like get just the first five documents or do something 123 00:08:54,020 --> 00:08:57,400 even different like just get the number of matching documents. 124 00:08:57,410 --> 00:09:00,630 You don't even want any document data themselves. 125 00:09:00,650 --> 00:09:04,650 So when we get a cursor back it opens up a lot more possibilities. 126 00:09:04,670 --> 00:09:08,280 Now we can explore all of this by heading over to the documentation. 127 00:09:08,360 --> 00:09:15,200 So if we go over to Google Chrome and we scroll down to our f methods for collection we have find one 128 00:09:15,260 --> 00:09:16,260 right here. 129 00:09:16,280 --> 00:09:18,770 We pass in the query which we did. 130 00:09:18,800 --> 00:09:24,350 We have our optional options which we did not specify and then down below we add the callback which 131 00:09:24,350 --> 00:09:30,830 we did specify if we go over to find though we can see that we still have the query and those optional 132 00:09:30,950 --> 00:09:31,760 options. 133 00:09:31,760 --> 00:09:35,120 But there is no callback as a third argument. 134 00:09:35,150 --> 00:09:41,540 Now we can see that we also get a return value right here of cursor and when we click that it's going 135 00:09:41,540 --> 00:09:44,190 to bring us over to something else in the docs. 136 00:09:44,270 --> 00:09:47,360 If we scroll down we have cursor sitting right here. 137 00:09:47,810 --> 00:09:53,030 So what we get back from find is indeed a cursor it is a pointer to data. 138 00:09:53,060 --> 00:09:55,780 There are all sorts of methods we can use with it. 139 00:09:55,850 --> 00:10:02,990 We can use things to limit the data like limit I can count the data up with count I can do other forms 140 00:10:02,990 --> 00:10:10,550 of aggregation or I can use one of the more popular methods to array to array is going to allow us to 141 00:10:10,550 --> 00:10:15,170 get back an array of documents which in this case is exactly what we want. 142 00:10:15,560 --> 00:10:16,200 So over here. 143 00:10:16,220 --> 00:10:17,870 What does that mean for us. 144 00:10:17,900 --> 00:10:22,610 It means that finder returns a cursor and the cursor has a 2 array method. 145 00:10:22,610 --> 00:10:27,170 So right here I'm going to call to array now to array. 146 00:10:27,170 --> 00:10:33,830 That is what takes the callback function where we either get the error or we get our matching documents. 147 00:10:33,890 --> 00:10:36,710 In this case we could call them users. 148 00:10:36,710 --> 00:10:41,360 Now let's go ahead and dump those to the council to see what we get since the error handling is going 149 00:10:41,360 --> 00:10:42,860 to be the same either way. 150 00:10:42,920 --> 00:10:45,160 I'm just going to temporarily ignore that. 151 00:10:45,350 --> 00:10:49,460 I'll use console log to just dump users to the console. 152 00:10:49,460 --> 00:10:52,640 We can save Mongo DB and test things out. 153 00:10:52,700 --> 00:10:59,150 Now I will comment out my call to find one just to clean up the output we see in the terminal down below 154 00:10:59,270 --> 00:11:02,140 and I'll restart the script I'll shut it down. 155 00:11:02,140 --> 00:11:04,450 Start it up once again and right here. 156 00:11:04,450 --> 00:11:05,380 What am I getting. 157 00:11:05,480 --> 00:11:12,380 I'm getting an array of three documents back where each document has an age of twenty seven. 158 00:11:12,530 --> 00:11:18,770 So using this simple call I was able to fetch multiple pieces of data from the database limiting them 159 00:11:18,830 --> 00:11:20,240 by some criteria. 160 00:11:20,240 --> 00:11:26,300 Now to further explain why cursors are being used we can take this call copy it and duplicate it down 161 00:11:26,300 --> 00:11:27,230 below. 162 00:11:27,230 --> 00:11:31,980 We're gonna switch from using the to array cursor method over to using count. 163 00:11:32,060 --> 00:11:37,550 Now count still takes in a callback and we get an error potentially or the count. 164 00:11:37,550 --> 00:11:40,090 So right here I can just call that count. 165 00:11:40,130 --> 00:11:42,290 Then I'll just print count to the console. 166 00:11:42,560 --> 00:11:47,020 So it's very similar to what we had above with a few minor changes. 167 00:11:47,030 --> 00:11:50,630 Now if we rerun the program we can see the output we're gonna get. 168 00:11:50,630 --> 00:11:56,800 So right here I get my array for that first call to find and for the second I get the number three. 169 00:11:56,810 --> 00:11:58,850 So this is the advantage of the cursor. 170 00:11:58,940 --> 00:12:04,850 Sometimes I want to get the data I want to get all of the individual fields back and in that case to 171 00:12:04,850 --> 00:12:06,510 array gets the job done. 172 00:12:06,590 --> 00:12:12,140 But if I do want to do something simple like count there's no need to fetch all of those records store 173 00:12:12,140 --> 00:12:16,810 them in memory in node j s only to get a single number back. 174 00:12:16,950 --> 00:12:23,550 Mongo DB can handle that for us instead of needing to transfer all of the documents across the network. 175 00:12:23,550 --> 00:12:26,310 It can just transfer that single integer. 176 00:12:26,370 --> 00:12:28,440 In this case the number three. 177 00:12:28,440 --> 00:12:33,960 So the cursor is a nice tool for us to be able to use and hopefully this example illustrates why we 178 00:12:33,960 --> 00:12:36,960 might not always want to get all of the data back. 179 00:12:37,020 --> 00:12:42,600 While we might want to sometimes do something a little bit different now it is challenge time where 180 00:12:42,660 --> 00:12:50,310 you're going to use our search methods find one and find to find documents in the tasks collection and 181 00:12:50,310 --> 00:12:51,060 right here. 182 00:12:51,060 --> 00:12:53,510 I have some challenge comments right here. 183 00:12:53,520 --> 00:12:58,830 Your challenge is to use find and find one with the tasks collection. 184 00:12:58,830 --> 00:13:05,760 So step one you're gonna use find one to fetch the latest task in that collection by its I.D. and you'll 185 00:13:05,760 --> 00:13:12,510 print that document to the console then you're going to use a call to find to attach all tasks that 186 00:13:12,510 --> 00:13:16,710 are not completed and you're going to print those to the console as well. 187 00:13:16,710 --> 00:13:18,690 Finally you're going to test your work. 188 00:13:18,690 --> 00:13:21,750 So when you run the script you should see one document print. 189 00:13:21,780 --> 00:13:27,810 The last task then the next thing that prints should be an array of documents all of the tasks that 190 00:13:27,810 --> 00:13:29,590 have not been completed. 191 00:13:29,610 --> 00:13:33,570 Take some time to knock that out using the code disgust up above. 192 00:13:33,570 --> 00:13:36,900 Test your work and when you're done come back and click play 193 00:13:40,810 --> 00:13:41,480 how would you do. 194 00:13:41,540 --> 00:13:47,180 Let's go ahead and kick things off by pulling up the tasks collection and robo 3D so we can see the 195 00:13:47,180 --> 00:13:47,630 data. 196 00:13:47,630 --> 00:13:48,710 We're working with. 197 00:13:48,710 --> 00:13:50,440 I have that sitting right here. 198 00:13:50,540 --> 00:13:54,880 Now the first thing was to grab the document the last one and buy I.D.. 199 00:13:55,040 --> 00:13:59,510 So I'm gonna edit that document just so I can copy it to the clipboard easily. 200 00:13:59,510 --> 00:14:02,940 I'll close the editor and I'll bring that over to mongo. 201 00:14:02,970 --> 00:14:05,110 Dot J S right here. 202 00:14:05,120 --> 00:14:11,600 D.B. dot collection since we are trying to access the tasks collection and right here I'm gonna use 203 00:14:11,600 --> 00:14:18,800 find one to find a document by its I.D. so any query object we're searching by I.D. and I'm searching 204 00:14:18,800 --> 00:14:28,220 by an object I.D. So I use new object I.D. passing in inside of quotes the object I.D. value. 205 00:14:28,370 --> 00:14:34,590 Now from there we provide that second argument which is our callback function we get a potential error 206 00:14:35,310 --> 00:14:39,190 and we potentially get the document which I'll call a task. 207 00:14:39,420 --> 00:14:45,660 Right here we can go ahead and provide the arrow function body and in here all I'm gonna do is dump 208 00:14:45,840 --> 00:14:47,150 task to the console. 209 00:14:47,160 --> 00:14:51,960 So console dot plug printing task. 210 00:14:51,960 --> 00:14:54,870 Now we can go ahead and test our work one step at a time. 211 00:14:54,900 --> 00:14:59,470 So right here I'll go ahead and rerun things I'll shut the program down. 212 00:14:59,510 --> 00:15:06,270 Start it up once again and I am indeed seeing that last task with a description of pot plants and a 213 00:15:06,270 --> 00:15:11,140 completed value of false which matches up with what I have over here. 214 00:15:11,220 --> 00:15:16,530 Next up step two was to find all of the documents that have not been completed. 215 00:15:16,530 --> 00:15:20,250 So right here for that we'll use D.B. dot collection. 216 00:15:20,250 --> 00:15:28,110 Once again we're looking in tasks and we're using find to find documents where it completed is equal 217 00:15:28,140 --> 00:15:29,550 to False. 218 00:15:29,640 --> 00:15:36,150 Now from here we can't just provide a callback function since remember bind returns a cursor. 219 00:15:36,150 --> 00:15:39,440 Now we could use other cursor methods to do other things. 220 00:15:39,540 --> 00:15:42,500 In this case though we do indeed want to print all of those documents. 221 00:15:42,510 --> 00:15:45,680 So I'll use to array when we use to array. 222 00:15:45,710 --> 00:15:50,030 It actually goes off to the server and fetches all of those documents. 223 00:15:50,040 --> 00:15:55,250 Right here we either have an error or we have our list of tasks. 224 00:15:55,320 --> 00:15:56,220 Perfect. 225 00:15:56,220 --> 00:16:02,040 Let's go ahead and print them console dialogue printing tasks. 226 00:16:02,050 --> 00:16:06,300 Now we're gonna go ahead and run our program for the final time. 227 00:16:06,370 --> 00:16:09,040 Down below I'll shut down the script. 228 00:16:09,040 --> 00:16:10,410 I'll start it up again. 229 00:16:10,420 --> 00:16:16,030 We have as the first piece of output our last item which was fetched by I.D.. 230 00:16:16,330 --> 00:16:21,670 Then we have our array with all of the documents all of the tasks that have not been completed. 231 00:16:22,000 --> 00:16:28,720 I have renew inspection and I have pot plants both which indeed have a completed value of false. 232 00:16:28,720 --> 00:16:31,420 I'm not seeing clean the house show up anywhere. 233 00:16:31,420 --> 00:16:33,960 Since that has already been completed. 234 00:16:34,010 --> 00:16:39,490 Now this example query is the kind of query you would use if you're trying to show someone all of these 235 00:16:39,490 --> 00:16:41,520 things they still need to do. 236 00:16:41,560 --> 00:16:48,790 Now that we know how to find our documents we have knocked out both C for create and R for read down 237 00:16:48,790 --> 00:16:49,240 below. 238 00:16:49,240 --> 00:16:53,820 I'm also going to remove the challenge comments since we're all done with that one. 239 00:16:53,890 --> 00:17:00,340 Now we do still have to cover you for update and D for delete but before we do we're going to take a 240 00:17:00,340 --> 00:17:05,800 quick break to talk about a very important asynchronous tool at our disposal. 241 00:17:05,800 --> 00:17:10,200 This is the promise and we're going to start talking about it in the next video. 242 00:17:10,330 --> 00:17:12,250 So let's go ahead and jump right in.