From the course: Web Servers and APIs using C++

Querying Mongo data - C++ Tutorial

From the course: Web Servers and APIs using C++

Start my 1-month free trial

Querying Mongo data

- [Instructor] We now have the MongoDB C++ driver in our Docker image. In order to use it we'll need to update our root Docker file, change a few lines in CMakeLists.txt and add code to main.cpp. Let's get started. So we're gonna open up the root Dockerfile. So here's hello_crow. We're not in bbox. We're gonna open up this root Dockerfile. We're gonna change where it says hello_crow to hello bbox:latest, and I'm gonna put a little space in there. This WORKDIR I'm going to make a copy of that line so I have two of them. The first one I'm gonna delete off the build from the end and I'm gonna type COPY. . which is just gonna copy our hello_crow source code onto our Docker image. Then after the second WORKDIR with the build on it I am gonna say RUN cmake . And I'm gonna say RUN make. And then I'm gonna keep the command that says /hello_crow. And that's gonna be it. I'm gonna save that off. Next we're gonna go into CMakeLists.txt. Inside of CMakeLists.txt the first thing I'm gonna do is here where it says find_package(Threads) I'm gonna put a space and add the REQUIRED here. Required just makes it so that in case it doesn't find this library it will error out of the build process, which is a good thing. You don't wanna build for five or 10 minutes and then find out something that you needed was missing once it was trying to link it. Then we're gonna add another find_package. And this find_package is looking for libmongocxx, and it too is required. Next I'm gonna just rearrange a couple of lines. So here on line 13 I'm gonna take the add executable and move it before the include directory. So it's just gonna say add_executable(hello_crow main.cpp). Then on line 13 I'm going to modify this line so that it says target_include_directories. I am gonna say hello_crow space. We're gonna keep the boost libraries, but I'm gonna add a PRIVATE right here. Then I'm gonna say space $ {} and then inside the curly braces I'm going to write LIBMONGOCXX_INCLUDE_DIRS. So that's our LIBMONGOCXX_INCLUDE_DIRS directories. Then on the final line the target link libraries, I'm gonna do a space here. I am gonna say another $ {}, and here I'm gonna do LIBMONGOXCC_LIBRARIES, and then I'm gonna save that off. Go to main.cpp, close to the top of the file, right underneath where it says include crow_all I'm gonna add some more includes, and the first ones that I'm gonna include are gonna be #include, and this is gonna be <fstream>, #include <iostream>, and we're gonna include <vector> and we're gonna include <cstdlib>, the C standard lib. And the final thing I'm gonna include is gonna be <boost/filesystem.hpp> and close that angle bracket. I'm gonna put a little space in here. Next I have three bson includes. The first one is gonna be <bsoncxx/builder/stream/document.hpp>. And I'm gonna do #include <bsoncxx/json.hpp>, and I'm gonna do #include <bsoncxx/oid.hpp>. This is working with Mongo's object ID. Then I'm gonna put one more space and then I've got four Mongo includes. So it's gonna be #include <mongocxx/client.hpp>, #include <mongocxx/stdx.hpp>, <mongocxx/uri.hpp>, and #include <mongocxx/instance.hpp>. Now I'm gonna add some using statements. There's gonna be seven bson using statements and one Mongo using statement. So using bsoncxx::builder::stream. Now there are gonna be six more of these. So I'm gonna just make copies of them. That's one, two, three, four, five, six, seven all together. First one's gonna be ::close_array, ::close_document, ::document, ::finalize, ::open_array, ::open_document, and finally the last one actually is not a stream, it is basic::kvp, for key value pair. And then we're gonna have a using mongocxx::cursor. Now we're gonna scroll all the way down to our main function. Inside of our main function, right after it says crow::SimpleApp app we're gonna go ahead and establish our connection with the database so we're gonna say mongocxx::instance. The variable name is inst with {}; then we're gonna say string mongoConnect= std::string and we're gonna call getenv, so we're gonna get an environmental variable, and this variable's name comes from Heroku. This is the thing that it told us on the settings page, it's MONGODB_URI. So we're gonna get that environmental variable because it's going to hold our connection string. And then we're gonna do a mongocxx::client and we're creating our connection and the variable's gonna be called conn. We're gonna have {}, here is what we're gonna instantiate this with, mongocxx::uri{} mongoConnect and then a ; and then we're gonna say auto collection = con we're gonna have two pairs of square braces and a semicolon. Inside the second one is gonna go the name of the collection, which for us is contacts. Inside of the first one, let us go to Heroku, go up to our database, we're gonna click on overview, click on mLab mongoDB. And it says database: this is the name of our database. I'm gonna do a command c to copy that name, go back to Atom, and then I'm gonna put some "" and inside those "" I'm gonna copy the name of our database. So we've got our name of our database, name of our collection here. Now I'm gonna scroll down and then just before our root route I am gonna create another route and we're gonna have app, and then the name of the route is gonna be contacts, and then after that we are gonna have some () and inside the () the first thing is gonna be some [] and in that [] this is our lambda capture. We want to capture the collection. So it's &collection. Then we're gonna have our parameters, we're not taking any. Then we're gonna have some {} and a ; and I'm gonna open this up right here between the {} and we're gonna say mongocxx::options::find and we're gonna create a variable called opts and we're gonna say opts.limit. So we're gonna use the mongolimit to limit the collection to the first 10 documents it finds. Then we're gonna say auto docs = collection.find. We're not gonna give it any query parameters but we are gonna pass in our options in order to limit it to the first 10. Then we're gonna do an std::ostringstream, space, and this is gonna be os. And then we're gonna do a range base for, so we're gonna say auto &&, two &&, doc : docs. We're gonna iterate over our documents. And for each one we are going to write out bsoncxx::to_json and we're gonna write out the document. And we'll also add a return \n and finally we're gonna return crow::response os. and we're gonna convert it to a stream and add a ;. All right so now we're gonna go back to the terminal. We need to do a cd :: and go to the root directory. Let's just do an ls, yep. That's the root and we are going to do a docker build and this should be familiar now, - -rm --squash -- no-cache -t hello_crow:latest . This should not take that long to run since it's only gonna build our source code and then link it. So it's gonna compile and link our source code in the Docker container. So the next thing that we need to do, first thing we're gonna do is we're gonna go back to Heroku, go to the settings tab, reveal our config vars. Here's our MONGODB_URI. I'm gonna click in this box and do a command a to select everything. And then I'm gonna do a command c to copy it. And I'm gonna come back to the terminal and I'm gonna type docker run -p 8080:8080. That's gonna open up my port. Then I'm gonna do a -e. The PORT I'm gonna pass in the port environment variable, so PORT=8080, space, and I'm gonna do another environment variable, -e and this is gonna be MONGODB_URI=, and I'm gonna have a pair of "", and then inside those "" I'm gonna do a command v to copy the connection string that I copied from Heroku. And I'm gonna do a space and then it's hello_crow:latest and I'm gonna hit enter. And we can see our server is now running on port 8080 so let's go to our browser. Let's go back here, do a refresh. We see we get our JavaScript message. And now let's try our new endpoint, contacts, and voila, we've got data. Let's just take a quick look. We can see that there's 10 documents that are being displayed here. The 10th one, the first name is Aila. So let's have just a wee bit of fun. We're gonna come back to Atom. Right here where it says opts.limit(10), just before that line I'm gonna say opts.skip(9); and I'm just gonna save that off. I'm gonna go back down to the terminal. I'm gonna do a control c, and then I'm gonna do an up arrow to get back to my build command for hello_crow. I'm gonna rebuild it. And again this shouldn't take that long 'cause it's just gonna compile and link. Then I'm gonna do an up arrow to get back to my command with all the connection information. So I'm gonna run the server. We're running again. I'm gonna go back to the browser, and we can see that Donnajean is contact number one, Aila is contact number 10. If I refresh the browser at this point, now Aila is contact number one and we've got nine new contacts. So congratulations, we've written our first MongoDO query in C++.

Contents