MongoDB & Node.js: Connecting & CRUD Operations (Part 1 of 4)
Rate this video
00:00:00Introduction to MongoDB and Node.js
Lauren Shafer, a staff developer advocate at MongoDB, introduces the video series aimed at helping developers learn to use MongoDB with Node.js.00:01:09Setting Up and Connecting to MongoDB
The video walks through setting up the environment, checking Node.js installation, and installing the MongoDB Node.js driver. It also covers creating a MongoDB database using MongoDB Atlas.00:02:01CRUD Operations Overview
Lauren explains CRUD operations and prepares to demonstrate each operation in MongoDB.00:03:04Understanding MongoDB Data Storage
The video explains how MongoDB stores data in BSON documents within collections and the importance of the `_id` field.00:04:00Creating Documents
Lauren demonstrates how to create new documents in a collection using `insertOne` and `insertMany`.00:05:00Reading Documents
The process of reading documents from a collection is shown, including querying for a single document with `findOne` and multiple documents with `find`.00:06:00Updating Documents
The video covers updating documents using `updateOne`, `updateMany`, and the `upsert` option.00:07:00Deleting Documents
Lauren concludes the CRUD operations by showing how to delete documents using `deleteOne` and `deleteMany`.00:07:57Closing Remarks
The video wraps up with a summary of the topics covered and a teaser for the next video on the aggregation framework.The primary focus of the video is to teach viewers how to perform CRUD operations in MongoDB using Node.js, as well as to provide an understanding of MongoDB's data storage structure.
🔑 Key Points
- How to connect to a MongoDB database from a Node.js script.
- Understanding of MongoDB's data storage in documents and collections.
- Demonstrations of CRUD (Create, Read, Update, Delete) operations.
- Introduction to the aggregation framework for advanced data manipulation.
🔗 Related Links
- https://mdb.link/free-fbYExfeFsI0
- https://mdb.link/community-fbYExfeFsI0
- https://mdb.link/connect-nodejs
- https://mdb.link/nodejs-crud
- https://mdb.link/nodejs-quickstart
- https://youtu.be/iz37fDe1XoM
- https://youtu.be/bdS03tgD2QQ
- https://youtu.be/9LA7_CSyZb8
- https://twitter.com/lauren_schaefer
- https://tiktok.com/@lauren_schaefer
- https://www.linkedin.com/in/laurenjanece/
- https://mongodb.prakticum-team.ru/developer.mongodb.com/community/forums/t/hey-friends-im-lauren/168
- https://mdb.link/subscribe
Full Video Transcript
are you using node.js do you want to learn to use mongodb if so this is the video series for you hey everybody i am lauren shafer and i am a staff developer advocate at mongodb i love helping developers be successful as they build their apps in this quick start video series i'll walk you through the basics of how to get started using mongodb and node.js together so today i'll walk you through how to connect to a mongodb database and then how to execute each of the crud operations if you're not familiar with that acronym crud it stands for create read update and delete now for those of you who prefer reading over watching videos i've got you covered i have an article series that covers the exact same content so check out the description below for a link also i have a github repo that contains all of the code you'll see me right here today again check that description below for a link with that let's jump right in the first thing we need to do is get set up i'm going to be working today in vs code but feel free to use whatever code editor you like the first thing i'll do is check that i have node installed so i'll run node v as you can see i have version 14.15.4 next up i want to install the mongodb node.js driver the node driver allows you to easily interact with mongodb databases from within nodejs applications you'll need the driver in order to connect to your database and execute queries so if you don't have the mongodb node.js driver installed you can install it with npm install mongodb alright and i can check what version i'm running with npm list mongodb as you can see i'm running the beta version of 4.0 the next thing we need to do is create a mongodb database now the easiest way to get started with mongodb is to use mongodb atlas atlas is mongodb's fully managed database as a service i love to use it because i don't like managing databases myself so this is atlas and i've already created a new project let's create a cluster now at a high level a cluster is a set of nodes where copies of your database will be stored now i'm going to choose to create a free cluster because i like free things um but there are a ton of options here you can choose from it's definitely worth exploring but i'm just going to skip over it for now and click create cluster creating a cluster takes a few minutes i don't feel like waiting so with the magic of editing i'm just gonna skip ahead now that our cluster is created let's put some data in it i'm gonna choose to load some sample data this will take a minute or two so once again i'm just going to jump ahead all right our data is loaded let's start working on connecting to our database so i'm going to click this connect button this dialog is going to walk me through how to get connected atlas has a built-in security feature it's super handy only certain ip addresses can connect to the cluster so i'm going to add my ip address now i'm going to create a database user so i'm going to name the user demo i'm going to input a password and be sure if you're following along with me note this username and password you are going to need it again later so now i get to choose my connection method i want to connect from a node.js script so i'll select connect your application i'll select nodejs as my driver and then i'm going to copy this connection string now that my database is set up it is time to code right that's the fun part so let's write a node.js script that connects to the atlas cluster i just created and just lists all the databases in that cluster i'm going to hop back over to vs code and i'm going to create a new file i'm going to name mine demo.js so first thing i'm going to do at the top of my file is get the client so i'll say const client equals require mongodb the client is what i'm going to use to connect to my mongodb database so i'm going to kick things off with a main function and let's make it asynchronous inside of this function i will connect to the mongodb cluster call functions that query the database and then disconnect from the cluster so the first thing i'm going to do inside of main is create a constant for my connection uri i'm going to paste the connection uri that i copied in atlas a few moments ago now i need to make sure i update my username and password to match the database user i created now just a note here the user name and password i'm using here are not my atlas credentials this is the database user you saw me create in atlas just a moment ago now that we have our uri we can create an instance of client so we'll say const client equals new client uri now i'm going to connect to my cluster so i'll say await client dot connect client.connect returns a promise so i'm using the await keyword to indicate that i should block further execution until that operation has completed now client.connect could throw an error so i'm going to wrap this call in a try catch and i'm not going to do anything fancy i'm just going to send that air to console.air now i want to be sure to close the connection to my cluster so i'm going to end the try catch with a finally statement and we'll put await client.close in there so once we have our main function written we need to call it so we'll say main and let's send any errors just out to the console so we'll say catch console.error all right let's save the script and run it so in my terminal i will type node demo.js and nothing happened that's actually good news that means that nothing blew up so let's actually do something with that connection let's list the databases in our cluster so i'm going to create a new function named list databases and i'm going to set the client as a parameter and let's make this an asynchronous function all right so to get our list of databases we'll use client dot db dot admin dot list databases and let's await these results before continuing on and then let's assign the results to a constant named databases list now that we have the list of databases i'm just going to print them out so i'll say dot console.log databases then i'm going to print each one so i'll say databases list dot databases dot for each and we'll uh let's call the param db and then let's just log each database name console.log dash db.name all right so my function is good now i just need to call it so inside of main let's scroll up i could say await list databases and i'm going to pass the client all right let's try this out let me save my file and i'm going to run it again and hey there is my list of databases so we know we're successfully connected we're pulling data out of our cluster pretty straightforward right okay so before we go any further let's take a moment to understand how data is stored in mongodb mongodb stores data in bson documents bson is a binary representation of json json stands for javascript object notation so when you read mongodb documentation you'll frequently see the term document but you can think of a document as simply a javascript object now for those of you coming from the relational database world you can think of a document as being roughly equivalent to a row in a table now mongodb stores groups of documents in collections now for those of you with relational database backgrounds you can think of a collection as being roughly equivalent to a table now every document is required to have a field named underscore id the value of underscore id must be unique for each document in the collection the handy thing is mongodb will automatically create an index on underscore id for you now you can choose to make the value of underscore id meaningful rather than a somewhat random object id if you have a unique value for each document that you'd like to be able to quickly search so let's take a look at some data in this video series i'm going to use the sample airbnb listings data set now the sample airbnb database contains one collection called listings and reviews this collection contains documents about airbnb listings and their reviews pretty straightforward title right so let's take a look at a document in the listings and reviews collection so here you can see the listing has an id a listing url a name a summary and so much more you can see a few different types in this document so we can see the name is a string the last script is a date and bedrooms is an integer now let's look at amenities amenities is an array now if we expand it we can see that it's storing an array of strings all right let's take a look at a dress a address is an object here you can see the address object has fields and values as well as another object inside of it let's take a look at one more let's look all the way down at the bottom of the document at reviews we can see reviews is an array and it's actually an array of objects so as you can see you have a lot of flexibility in how you model your data when you use mongodb for more information on how mongodb stores data check out the mongodb back to basics webinar that i co-hosted with ken alger and as always i'm going to put a link in the description below all right now that we've connected to a database and we know how mongodb stores data let's kick off the crud operations and remember crud stands for create read update and delete so i'm going to return to vs code and i'm going to keep working in the same file so let's start with the c and crud that's create i'm going to begin by creating a new airbnb listing so i'm going to create a new function named create listing and let's make this an async function for the prams we need that client as well as the new listing we need to create so to insert the new listing we will say client dot db now we want the sample airbnb database and inside of that database we need to access the collection named listings and reviews from that collection we can call insert one we'll pass the new listing to insert one insert one will insert a single document into the collection the only required parameter is the new document that will be inserted if our new document does not contain the underscore id field the mongodb driver will automatically create an id for the document super handy so that's all we need to pass to insert one we want to wait for the results so i'll add a weight here let's assign the results that come back to a constant named result and finally let's log the id of the newly inserted document so i'll say console.log new listing created with the following id result dot inserted id all right that's all we have to do for this function so i'm gonna head back up to main i'm gonna get rid of this call to list databases and instead i'm gonna call create listing and i'm going to pass the connected client i'm also going to create an object for the new listing so i'm just going to set a few fields for this listing let's give it a name how about lovely loft and for the summary let's say a charming loft in paris for bedrooms i'll set it to one for bathrooms i'll also set it to one let's be sure to await the results of create listing all right let me save this and let's run it and we can see we've created a new listing nice now note that i did not include a field named underscore id in the document so the mongodb driver automatically created an underscore id for me all right so now we know how to create a single document sometimes you'll want to insert more than one document at a time so you could choose to repeatedly call insert one over and over the problem is that depending on how you've structured your code you may end up waiting for each insert operation to return before beginning the next and this could result in slow code nobody wants that so instead of calling insert one i could call insert many insert many will insert an array of documents into your collection insert many has one required parameter and that is an array of documents that should be inserted let's write a function to create multiple airbnb listings so i'll say function create multiple listings and let's make this an asynchronous function for params let's pass the client as well as an array of new listings now the inside of this function is going to look very similar to what we did in the previous function so we'll say access the sample airbnb database and then the listings and reviews collection and instead of calling insert one i'm going to call insert money and we'll pass the new listings to insert many let's assign the results to a constant named results and then let's just log how many listings were inserted as well as the ids of the new documents so i'll say console.log result.insertedcount that's how many new listings created with the following ids and then let's just log those ids so i'll say console dot log result dot inserted ids let's call this function so going back up to main let's get rid of this call to create listing we'll say await create multiple listings and i'll pass the client now i've prepped a couple of listings to insert so i'm just going to paste those here so you don't have to watch me type them now note every document does not have the same fields which is perfectly okay i'm guessing that those of you who come from the relational database world will find this incredibly uncomfortable but it really will be okay when you use mongodb you get a lot of flexibility in how to structure your documents so if you later decide you want to add schema validation rules so you can guarantee your documents have a particular structure you can all right let me save this and i'm going to run it all right we can see three new listings were created and we have a list of their ids it worked so that takes care of the c in crud let's move on to our read so let's begin by querying for an airbnb listing in the listings and reviews collection by name let's create a function named find one listing by name and let's make this an async function for the params let's use the client and the name of the listing that we want to find all right let's write our query so we'll say client dot db sample airbnb dot collection listings and reviews dot find one find one will return the first document that matches the given query even if more than one document matches the query only one document will be returned find one has only one required parameter and that's a query of type object the query object can contain zero or more properties that mongodb will use to find a document in the collection if you want to query all documents in a collection without narrowing your results in any way you can simply send an empty object since we want to search for an airbnb listing with a particular name we're going to include the name field in the query object that we passed to find one so we'll set the name of the listing right here all right and let's await this result and let's store the results in a constant named result depending on what name is passed we may or may not get a result so if we get a result let's log found a listing in the collection with the name name of listing and then let's log the result else we didn't get a result so we'll say console.log no listings found with the name name of listing so let's call this function heading back up to main i'm going to delete this call to create multiple listings instead i'm going to say await find one listing by name and i'll pass the client and the name infinite views now this is one of the documents i created a minute ago when i called create money so let me save this file clear the terminal and run the script and there it is we can see our document for infinite views so now you know how to query for one document let's discuss how to query for multiple documents at a time let's say we want to search for all airbnb listings that have a minimum number of bedrooms and bathrooms so let's create a function let's call it find listings with minimum bedrooms bathrooms and most recent reviews wow okay that's a really long function name we probably could be more concise but it's fine moving on let's make this an async function for params as always we're going to take a client now we actually need several other params so let's use destructuring so we want to set a minimum number of bedrooms and we'll set the default to zero minimum number of bathrooms again we're gonna set the default to zero and maximum number of results and we'll set that to numbers max save integer so how are we going to find multiple documents we can use find similar to find one the first parameter for find is the query object you can send zero to many properties inside the query object so let's start building our query so we'll start how we always do client dot db sample airbnb dot collection listings and reviews dot find we know we want to check that the listings have a minimum number of bedrooms so we'll say bedrooms is greater than or equal to minimum number of bedrooms remember that's our function argument and let's do the same thing for bathrooms we'll say bathrooms is greater than or equal to minimum number of bathrooms so here i'm using the dollar gte which means greater than or equal to so i just want you to be aware the mongodb provides a variety of other comparison query operators that you can use in your queries so check out the official documentation for more details on those operators okay so this query is going to return a cursor a cursor allows traversal over the result set of a query so let's draw results of this query as a constant named cursor you can choose to use cursor's functions to modify what documents are included in the results for example let's say we want to sort our results so that those with the most recent reviews are returned first so i could choose to sort by last review in descending order which is the minus one so this query would actually match 192 documents in the collection i don't want to process that many results inside of my script instead i want to limit the results to a smaller number of documents so at the end of this query i can chain limit as the name implies limit will set the limit for the cursor now that i have this cursor i could choose to iterate over this cursor to get the results one by one instead i'm going to retrieve all of the results in an array so i'll call cursors2 array function the result is a promise so i'll add a weight here and then i'm going to store this in a constant named result i've written some logging code that i'm just going to paste in so you don't have to watch me type it what it's doing is printing out a summary of each listing let's call this function so heading all the way back up to main let's get rid of this call and let's say a weight find listing with minimum bedrooms bathrooms and most recent reviews and i'll pass the client and then i'll set the minimum number of bedrooms to four the minimum number of bathrooms to two and the maximum number of results let's do 5. so let me save the file i'm going to clear the terminal and let's run the script all right i'm going to expand the terminal and we can see five listings that each have at least four bedrooms and two bathrooms pretty snazzy right all right we are halfway through the crud operations we are doing it all right now that we know how to create and read documents let's discover how to update them let's begin by updating a single airbnb listing in the listings and reviews collection we can update a single document by calling update update one has two required parameters the first required parameter is the filter which is used to select the document to update you can think of the filter as essentially the same as the query param that we used in find one to search for a particular document you can include zero properties in the filter to search for all the documents in the collection or you can include one or more properties in order to narrow your search now the other required param is the update operations to be applied to the document mongodb has a variety of update operators you can use such as increment set unset and a bunch of others so check out the official documentation for a complete list of the update operators and their descriptions update 1 will update the first document that matches the given query even if more than one document matches the query only one document will be updated so let's create a function that will update an airbnb listing with a particular name so let's name it update listing by name as usual we'll make it an async function and for params let's use the client the name of the listing and the updated listing so let's write our query we'll say client dot db sample airbnb dot collection listings and reviews dot update one now remember we need to pass two arguments so first is the filter we want a query by name so we'll filter where name is equal to the name of the listing for the second argument we need to pass the update operation we'll use dollar set and we'll pass the updated listing set will set new values for new or existing fields in the document that we are updating the document that we passed is set will not replace the existing document so any fields that are part of the original document but not part of the document that we passed to set will remain as they are okay so this looks good let's await the results and let's assign them to a constant named result all right last thing we want to do in this function is log the results let's log how many documents matched our filter so we'll say console.log result.matchedcount documents matched the query criteria and then let's log how many documents were updated so we'll say console.log result dot modified count documents was were updated okay let's test this out so i'm going to head back up to main i'm going to delete this and i'm going to call my update function so i'll say await update listing by name i'll pass the client and i want to update the infinite views property that i keep working with and i think i'm going to update it so it has six bedrooms and eight beds okay looks good let's run it so let me clear my terminal and i'm going to run the script all right excellent we can see one document matched the query criteria and one document was updated love it now let's take a few minutes to talk about upsert upsert is one of the options you can choose to pass to update one upsert is a super handy feature it allows you to update a document if it exists or insert a document if it does not for example let's say you wanted to ensure that an airbnb listing with a particular name had a certain number of bedrooms and bathrooms if you did not have upsert you'd first use find one to check if the document existed if the document did exist you'd use update 1 to update the document if the document did not exist you'd use insert one to create the document when you use upsert you can combine all of that functionality into one single command so let me show you how this works i'm going to create a function named upsert listing by name for params it's gonna be the same as our last function a client the name of the listing and the updated listing and let's make this function async this query is going to be very similar to the one i just wrote so as any great developer does i'm just going to copy and paste so i'll copy that query and i'm going to paste it in my new function the only thing i need to change is i'm going to pass an optional param i will set upsert to true now let's add some logging let's print how many documents matched our filter so we'll say console.log result.matchedcount documents matched the query criteria then let's check if anything was upsetted we'll say if results.upsertedcount is greater than zero console.log one document was inserted with the id result dot abserted id since we're calling update one we know only one document is going to be inserted else will log how many documents were updated so we'll say console dot log result dot modified count documents was were updated looks good let's try it out back up to maine we'll replace this call with our new one so let's say if we aren't sure if a listing named cozy cottage is in our collection or if it does exist it might hold all data either way we want to ensure the listing that exists in our collection has the most up-to-date data so we'll say await upsert listing by name and pass the client now the name of the listing i want to upset is cozy cottage for the document i want to upsert i'm going to set the name to cozy cottage i'm also going to set the number of bedrooms to 2 and the number of bathrooms to one so let's save the file i'm going to clear the terminal and run the script all right we can see zero documents that match the query criteria so one document was inserted now let's say the owners do renovations they add on an extra bathroom so i can use this same function call and just update the bathrooms to two so let me do that and i'll save this and i'm going to run it again and here we can see one document matched the query criteria and one document was updated so upser can come in pretty handy now sometimes you want to update more than one document at a time in this case you can use update many now like update 1 update many requires that you pass a filter of type object and an update of type object you can choose to include options as well and upsert is one of those options let's say that i need to ensure that every document has a field named property type let's create a new function called update all listings to have property type as usual i'm going to make this an async function and in this case i only need one param and that's the client let's write a query to update any listing that does not have a field called property type so i'll say client dot db sample airbnb dot collection listings and reviews dot update many for our filter we'll check to see if the property type field exists so we'll say property type exists is false so where the field does not exist then we need to pass our update operation so we'll use dollar set like we did previously and we'll set property type to unknown update many will return a promise so let's await the results and then let's assign them to a constant named result let's just add some logging so let's log how many documents match our filter so we'll say console.log results.matchedcount documents matched the query criteria and then let's log how many documents were actually updated so we'll say console dot log result dot modified count documents was or were updated so let's try this out heading back up to main we'll say await update all listings to have property type and we'll pass the client so let's save i'm going to clear my terminal and let's run the script okay we can see six documents did not have the property type field set and six documents were updated now all of the documents in our collection have the property type field set so if we take a look in the collection we can see that the cozy cottage document i created earlier in this video now has property type set to unknown listings that contained a property type before we called update many they remain as they were for example the spectacular modern uptown duplex listing still has property type set to apartment so those are the basics of updating documents in mongodb all right now that we know how to create read and update documents let's tackle the final crud operation delete let's begin by deleting a single airbnb listing in the listings and reviews collection we can delete a single document by calling delete1 delete one has one required parameter a filter of type object the filter is used to select the document to delete you can think of the filter is essentially the same as the query param we used in find one and the filter param we used in update one you can include zero properties in the filter in order to search for all the documents in the collection or you can include one or more properties and narrow your search delete one will delete the first document that matches the given query even if more than one document matches the query only one will be deleted okay so let's create a function to delete an airbnb listing with a particular name so let's name this function delete listing by name for params let's use the client and the name of the listing we want to delete and let's make this an async function all right let's write our query we're going to start the same way we always do and if you're thinking lauren you really should have made the collection a constant so you didn't have to type this every time i agree this was a mistake but we're going to stick with this pattern anyway so we'll say client dot db sample airbnb dot collection listings and reviews dot delete one we want to delete the document where the name is equal to the name of listing delete one returns a promise so i'm going to add a wait here and then let's assign the result to a constant named result finally let's log how many documents were deleted so we'll say console.log result dot deleted count documents was or were deleted let's try this out let me scroll back up to main and let's call the delete function so i'll say await delete listing by name i'm going to pass the client and let's delete the listing named cozy cottage so i'll save the file i'm going to clear the terminal and let's run the script and we can see one document was deleted now i can actually run this again and this time we can see that no documents were deleted which makes sense since i just deleted it so that covers delete one sometimes you want to delete more than one document at a time in this case you can use delete many like delete one delete many requires that you pass a filter of type object you can choose to include options as well let's say we want to create a function that will remove documents that have not been updated recently so let's say function delete listings scraped before date that scraped before date that's the date we're going to use so let's make this an async function for params we're going to use that client like we always do and the cutoff date for old documents that should be deleted all right let's write our query await client.db sample airbnb dot collection listings and reviews dot delete many now we want to delete documents where last scraped is less than the date that was passed to the function so delete many returns a promise so we will await the result and let's assign the result to a constant named result last thing we'll do in this function is log how many documents were deleted so we'll say console.log result.deletedcount documents was or were deleted by now you probably know what i'm going to do next i'm going to head back up to main and let's get rid of this let's delete listings that were scraped before february 15 of 2019 so we'll say await delete listings scraped before date client new date 2019 to 15. now for the final time in this video let's save the file i'm going to clear the terminal and let's run the script all right 606 documents were deleted that's way easier than manually checking for old documents and deleting them and with that we have wrapped up the basics of delete we covered a lot today so let's recap today i showed you how to connect to a mongodb database from a node.js script and then how to retrieve a list of databases next i shared how mongodb stores data in documents and collections then i showed you the basics of creating reading updating and deleting data if you want to reference the material i covered today in the future check out the blog series i wrote that covers exactly what i showed you today also i have a github repo that contains all of the code i showed you today i will put the links to both of those in the description below if you want to continue learning and i hope you do check out the next video in this series where i will cover the aggregation framework now i know the name aggregation framework it can seem a little intimidating but it is super powerful and it can be game changing when you start working with mongodb you are not going to want to miss this video that video is going to be releasing soon and i will drop a link to it in the description below when it is live all right that is all i have for you today thanks so much for watching i hope you enjoy using mongodb you