The basics of MongoDB
Since MongoDB is largely powered by JavaScript, the mongo shell acts as a JavaScript environment. In addition to being able to execute regular Mongo queries, you can also execute standard JavaScript statements. Most of the items mentioned earlier in the JavaScript primer apply directly to the mongo shell as well.
In this next section, we will focus primarily on the various ways to perform standard create, read, update, delete (CRUD) operations via the mongo shell.
The mongo shell
To access the mongo shell, simply execute mongo
from any terminal. The mongo shell requires the mongod
server to be currently running and available on the machine as the first thing it does is connect to the server:
$ mongo MongoDB shell version: 2.4.5 connecting to: test >
By default, when you first launch Mongo, you are connected to the local server and set to use the test
database. To display a list of all databases on the server, use the following command:
> show dbs
To switch databases to any of those listed in the output of show dbs
, use the following command:
> use chapter3 switched to db chapter3
An interesting thing to make note of is that if you use use
on a database that doesn't exist, one is instantly created automatically. If you are using an existing database and want to view a list of collections in the database, execute the following command:
> show collections
In the case of my chapter3
database, I had no existing collections since it was automatically generated as a new database for me.
Inserting data
Since we are working with the chapter3
database that is brand new, there are currently no collections in the database. You can use any collection (table) you want by simply referring to a new collection name with the db
object:
> db.newCollection.find() >
Performing a find
operation on an empty collection simply returns nothing. Let's insert some data so we can experiment with some queries:
> db.newCollection.insert({ name: 'Jason Krol', website: 'http://kroltech.com' }) > db.newCollection.find().pretty() { "_id" : ObjectId("5338b749dc8738babbb5a45a"), "name" : "Jason Krol", "website" : "http://kroltech.com" }
After we perform a simple insertion (of basically a JavaScript JSON object), we perform another find operation on the collection and get our new record returned this time with an additional _id
field added. The _id
field is Mongo's method of tracking a unique identifier for every document (record). We also chained the pretty()
function to the end of the find that outputs the results a little more nicely.
Go ahead and insert a few more records so you have some data to play with in the next section when we go over querying.
Querying
Querying and searching for documents in a MongoDB collection is pretty straightforward. Using the find()
function by itself with no parameters will return every document in the collection. To narrow down the search results, you can provide a JSON object as the first parameter with as much or as little specific information to match against, as shown in the following code:
> db.newCollection.find({ name: 'Jason Krol' }) { "_id" : ObjectId("533dfb9433519b9339d3d9e1"), "name" : "Jason Krol", "website" : "http://kroltech.com" }
You can include additional parameters to make the search more precise:
> db.newCollection.find({ name: 'Jason Krol', website: 'http://kroltech.com'}) { "_id" : ObjectId("533dfb9433519b9339d3d9e1"), "name" : "Jason Krol", "website" : "http://kroltech.com" }
Note that with each result set, every field is included. If you want to only return a specific set of fields with the result, you can include a map as the second parameter to find()
:
> db.newCollection.find({ name: 'Jason Krol' }, { name: true }) { "_id" : ObjectId("533dfb9433519b9339d3d9e1"), "name" : "Jason Krol" } > db.newCollection.find({ name: 'Jason Krol' }, { name: true, _id: false }) { "name" : "Jason Krol" }
Note that the _id
field will always be included by default unless you specifically state that you don't want it included.
Additionally, you can use query operators to search for things that are within ranges. These include greater than (or equal to) and less than (or equal to). If you wanted to perform a search against a collection of homework, and you wanted to find every document with a score within the B range (80-89), you can execute the following search:
> db.homework_scores.find({ score: { $gte: 80, $lt: 90 } })
Finally, you can use regex
while performing a search to return multiple matching documents:
> db.newCollection.find({ name: { $regex: 'Krol'} })
The preceding query will return every document that contains the word Krol
. You can get as advanced as you want with the regex
statements.
If you knew that you were going to be returning multiple documents on a query and only wanted the first result, use findOne()
in place of a regular find()
operation.
Updating data
To update a record, use the update()
function but include a find
query as the first parameter:
> db.newCollection.update({ name: 'Jason Krol' }, { website: 'http://jasonkrol.com' })
There's a bit of a catch here. If you perform a new find({ name: 'Jason Krol' })
operation, something strange happens. No data is returned. What happened? Well, the second parameter in the update()
function is actually the new version of the complete document. Since we only wanted to update the website
field, what actually happened was that the document that was found was replaced with the new version that consists of only the website
field. To reiterate, the reason this happens at all is because with NoSQL such as MongoDB, the document does not have a set number of fields (like a relational database does). To fix this problem, you should use the $set
operator instead:
> db.newCollection.update({ name: 'Jason Krol' }, { $set: { website: 'http://jasonkrol.com'} })
There may be a time when you want to update a document, but the document itself may or may not exist. What happens when the document does not exist, and you'd like for a new one to be created instantly based on the updated values you provide? Well, there's a handy function just for that. Pass {upsert: true}
as the third parameter to the update()
function:
> db.newCollection.update({ name: 'Joe Smith' }, { name: 'Joe Smith', website: 'http://google.com' }, { upsert: true })
If we have a document with a name field that matches 'Joe Smith'
, the website field will be updated (and the name
field preserved). However, if we do not have a matching document, a new one will be created automatically.
Deleting data
Deleting documents works almost exactly like find()
except instead of finding and returning results, it deletes those documents that match the search criteria:
> db.newCollection.remove({ name: 'Jason Krol' })
If you want the nuclear option, you can use the drop()
function that will remove every document in a collection:
> db.newCollection.drop()