Getting Started With MongoLab And The MongoDB Shell
Yesterday, I blogged about MongoDB: The Definitive Guide by Kristina Chodorow. It is an excellent book and has gotten me really interested in learning more about MongoDB. Apparently, MongoDB is really easy to download, install, and run locally; but, for some reason, I wanted to try running it as a remote database. So, I signed up for MongoLab - a hosted MongoDB platform that has a free developer sandbox. And, within minutes, I had created my database, connected to it from the Mongo Shell, and was performing CRUD (Create, Read, Update, and Delete) operations!
To start with, I used the Homebrew package manager to install MongoDB:
brew install mongodb
The installation was very easy and went off without error.
Then, I signed up for a MongoLab account and created a database using the free developer sandbox. This process was also very easy! Once logged-in, I clicked on the Create New button to create a new database:
NOTE: Click on the images to view full 1242px versions.
MongoLab allows you to select the Cloud provider for your MongoDB database; I don't really know one provider from another, so I just went with Amazon Web Services, which was selected by default. Then, I chose to use the free developer sandbox, which has limitations, but is perfect for some experimentation.
I am not exactly sure about this following statement, but I believe that the database name you choose - within the developer sandbox - has to be unique. I say this because when I went to choose the database name, "Ben," MongoLab complained that the given name was already taken. I assume this is a byproduct of the shared sandbox and will not be an issue with a dedicated plan.
Once I created the new database, it was listed in my Database data-grid. From there, I clicked on the database record to finish the configuration:
When you go to the database detail page for the first time, MongoLab will prompt you to create a Database User with credentials that you can later use to open an authorized connection.
After you create the user, you can find the database connection string at the top of the detail page.
Now that I had MongoDB installed and my MongoLab account setup and configured, it was time to start writing some actual MongoDB code.
By default, when you run the mongo shell [mongo], it attempts to connect to the server that you would have normally started using the mongod service. However, in this case, I don't want to use the local database - I want to connect to my MongoLab hosted MongoDB database. As such, I had to open the mongo shell with the "--nodb" flag. This will start the shell without attempting to open a connection:
mongo --nodb
At this point, I could have created a connection object in the Shell; however, one thing from, "MongoDB: The Definitive Guide," that intrigued me was the ability to load and run JavaScript files in the MongoDB shell. This seemed like a great opportunity to try that out - I could create a "connection" script:
mongolab.js - My MongoLab Connection Script
// Because we are going to be using a remote connection, be sure
// to start the MongoDB Shell (mongo) with the --nodb flag. Then,
// we can connect and define our own db instance.
// Connect to the MongoLab database.
var connection = new Mongo( "ds045628.mongolab.com:45628" );
// Connect to the test database.
var db = connection.getDB( "bennadel-test" );
// Authorize this connection.
db.auth( "**************", "**************" );
print( "> MongoLab connection and DB defined." );
Here, I am creating a connection object using the connection string provided on the MongoLab database detail page. I can then run this script in the Shell using the load() command:
Ben:mongodb ben$ mongo --nodb
MongoDB shell version: 2.4.6
> load( "mongolab.js" );
> MongoLab connection and DB defined.
true
>
This has re-defined the "db" variable which I can now use to start interacting with the MongoLab. But, I really love this idea of being able to run JavaScript files directly in the Shell. So, I set up another JavaScript file to load up some sample data:
friends.js - My Sample Data Script
// Clear any existing data from the friends collection.
db.friends.remove();
print( "> Friends collection has been reset." );
// Set up the randomly genreated friends.
var names = [
"Tricia", "Joanna", "Kim", "Anne", "Libby",
"Sarah", "Kate", "Kristina", "Samantha", "Tina"
];
// Add each name to the collection.
names.forEach(
function( name ) {
var friend = {
name: name,
age: ( 18 + Math.floor( Math.random() * 50 ) )
};
db.friends.insert( friend );
}
);
print( "> Friends collection has been populated with test data." );
Here, I am inserting 10 friend "documents" with randomly-selected ages. I ran this script in the Shell using the same load() command:
> load( "friends.js" );
> Friends collection has been reset.
> Friends collection has been populated with test data.
true
>
At this point, I now have my connection open and my sample data ready to go; I can simply start interacting with the hosted MongoDB database:
> var tricia = db.friends.findOne( { name: "Tricia" } );
> tricia
{
"_id" : ObjectId("5237abd431c37cb59a3d2463"),
"name" : "Tricia",
"age" : 49
}
>
> tricia.age = 35;
35
> db.friends.save( tricia );
>
> db.friends.findOne( { name: "Tricia" } );
{
"_id" : ObjectId("5237abd431c37cb59a3d2463"),
"name" : "Tricia",
"age" : 35
}
Once you load a script using the load() command, there's nothing that prevents you from loading the script again. In fact, I found the Mongo shell rather frustrating; so, I created a "test" script and just kept loading it / running it over and over again. I found it much easier to write MongoDB scripts in my SublimeText editor than in the command-line shell.
Anyway, you could have done all of this using the local mongod server; but, there's something fun about connecting to and interacting with a remote machine. Maybe it just adds a layer of novelty for me.
Non Sequitur
As easy as MongoDB was to get up and running, using it definitely makes me feel like a child. Simple things, that are second-nature in SQL (Structure Query Language), feel like Hurculean tasks in MongoDB. This is not a short-coming of MongoDB but, rather, a byproduct of a completely new syntax applied in a completely different paradigm. It's frustrating, and incredibly humbling; but, also , immensely exciting!
Want to use code from this post? Check out the license.
Reader Comments
Thanks for including MongoLab in such a detailed blog post! It's amazing how every day there are many developers that are just hearing about MongoDB and trying it for the first time. Very exciting time to be a part of the community.
Cheers!
@Chris,
My pleasure - seems to be a great service! Looking forward to learning more about MongoLab and MongoDB.
@Ben,
Any time you have questions about your MongoDB on our service, feel free to write us at support[AT]mongolab.com. We're here to make sure your (future) apps are a success, and that at the end of the day you love working with MongoDB.
Happy hacking!
Hi Ben,
1) Thanks for this detailed post.
2) Just noticed the link for the 3rd screenshot wrongly points to the big picture for the 1st one.
3) It is not clear to me if one needs to already have an account with one of those cloud providers in order to be able to work with MongoLab like this?
Greets,
Johan
@Johan,
Oh, nice catch! I'll update the link today.
As far as an account on the other servers, at least for the Sandbox, you do not. I don't think you need an additional account for any of their services. I believe that's part of the beauty - they do all the hosting management and scaling for you behind the scenes. You just sign up for a MongoLab account and they do the rest (more or less).
As for why you can choose between different cloud providers? I am not 100% sure. I think a big part of it has to do with latency. You wan your DB serves to be a *physically close* to your application servers as possible so the time to transmit data over the wire is a small as possible.
But that's just my guess.
@Johan @Ben,
You don't need an account with cloud providers to use any of the MongoLab plans. However, for the big reason that Ben mentioned, there are latency issues if you do not host your DB and application servers as close as possible- physics & computer science :).
In addition to faster latency, there are also security benefits as most of the major cloud providers have technology in place to prevent packet sniffing when VMs communicate over their internal network.
That's why we give our users many options for providers- so that they can host their database wherever their application resides.
@Chris,
Good stuff! Thanks for the clarity. That makes a lot of sense.
Great post, and cheers for pointing us towards MongoLab! I just setup my own sandbox account to play around, and it was as easy as you described. I guess AWS can no longer be used for Development (Single node) purposes, so I just tried Joyent and that gave me the free option.
@Dominick, there definitely still are development AWS sandbox plans. please email us at support@mongolab.com and we'll get it straightened out!
Where did you place your files in relation to mongodb? I tried placing them all over the place and always get:
Thu Jan 30 11:35:32.248 file [mongolab.js] doesn't exist
Thu Jan 30 11:35:32.248 Error: error loading js file: mongolab.js
Hello Ben,
I have been working with MongoLab for a while now and it took me some time to understand te pros and cons of it. Read http://www.sarahmei.com/blog/2013/11/11/why-you-should-never-use-mongodb/ to understand when to use a JSON store. Anyway, I started out using MongoLab for a pet project and am stuck now.
I have a collection of several documents and I want to retrieve all documents that have an _id value that is present in an array - using a REST api call. To query _one_ document I use
https://api.mongolab.com/api/1/databases/ishare/collections/contacts?apiKey=xxx&q={"_id":{"$oid":"5378f3c4e4b067b3961fff55"]}}
Do you have any idea how to retrieve all docs with a value that is present in an array supplied in the query parameter?
@Marc,
ok, for anyone wondering the same here's the answer:
https://api.mongolab.com/api/1/databases/DBNAME/collections/COLLNAME?apiKey=APIKEY&q={"_id":{"$in":[{"$oid":"ID1"},{"$oid":"ID2"}]}}
will retrieve all documents with an _id of ID1 or ID2
i am getting below error pls help
> load(D:\mypath\one.js)
2015-02-11T13:22:38.447+0530 SyntaxError: Unexpected token :