MongoDB refresher
Just to refresh what I learnt about MongoDB a few years back when I was doing the course from MongoDB University.
What is MongoDB? A few pointers:
- It is document store, schema-less i.e it doesn’t force each document to have the same structure.
- Stores data in JSON format(internally as BSON).
- Doesn’t support joins or transactions(but seems like they added transactions later, will need to go through it).
- Use the mongo client to interact with the mongoDB server. Uses very simple API.
- Do queries like
db.dbname.insert({a:1, b:2})
- Use JavaScript to do things in the mongo shell. Example :
var j = db.names.findOne(); j.name="change"; db.names.save(j);
- You usually embed the data that is related inside the document(nested object). To embed or not to embed will depend on whether the values that you are embedding have usefulness outside the document. Example : In a typical Blog DB, tags on a post are related tightly and don’t need to be updated globally so they can be part of the post document.
- Mongodb has a 16Mb limit for a document. In such cases where you can breach this limit make a non-embedded item.
Quick CRUD reference
Mongo doesn’t have its own query language as SQL, the (mongo)clients interact with API using the protocol used by Mongo. Mongo stores document as BSON internally which is binary representation of JSON and it supports some more data types than are supported by JSON, these data types are handled by the mongo drivers.
Creating new collection
Collections get automatically created when you run an insert.
E.gdb.collectionName.insert(document);
Replace collectionName
and document
above with, name of your collection and the JSON data that you want to insert.
Retrieve one record from the collection : findOne
db.collectionName.findOne({"name":"abs"})
Will return one document where field name
is abs
The second parameter will allow you to select only the fields to be returned just like SELECT f1, f2 in sql.
The _id field is always returned. To not get that we do something like
db.collectionName.findOne({"name":"abs"}, {"_id":false})
Retrieve all records
Use db.collectionName.find()
. The find method will retrieve all of the documents in a collection. but instead of outputting all of it, it will only return 20 documents at a time.
Rest of the documents can be obtained through using the “it” keyword. A cursor is maintained on the server for giving out the next batch, and it dies after 10 mins of no use.
This method has same API as findOne
Comparison Operations
Use logical comparison like $eq, $gt, $gte, $in, $lt, $lte, $ne, $nin
by making a sub-object for the column.
E.g db.collectionName.find({"score":{$gt:40}});
Inequalities on strings will only work if the the value compared is a string.
E.g db.collectionName.find({"name":{$gt:"n"}});
The lexicographical values are compared.
Operators
$exists checks whether the field is defined in the document
$type used to check the type of field, but you have to specify the type id which will be found in BSON doc
$regex for regular expressions.
$or, for logical OR it is a prefix operator, queries to be “or”ed have to be placed in a array which has a key as $or
E.g db.collectionName.find({$or:[{"name":"shyam"}, {"name":"ram"}]})
$and is similar in usage, use it for logical AND.
Searching inside an array.
Arrays are searched for strings. So if you search in tags:[“one”,”two”] for “one” like db.collectionName.find({"tags": "one"});
.
It will return all documents containing “one” in the “tags” field.
It looks at only depth 1 of array doesn’t go any further inside.
Operators $in and $all
These operators searches withing a array field.
$in is OR and $all is AND i.e $in will match any & $all will match only if all entries exist.
E.g: db.collectionName.find({"tags": {$all:["one", "two"]}});
Remember that MongoDB makes byte by byte matching, so if there is nesting in a field(e.g email:{work:"a@b.com",home:"a.com"}
), then either you have to specify the complete field value(the complete embedded value) or use the dot notation.
Pseudo E.g email.work : "a@b.com"
Cursors
Allow you to modify the way the results will be returned from your query.
E.g cur = db.collectionName.find();null;
Now you can apply functions like cur.limit(5).sort({"name":-1})
and then use cur to output the results.
Count
Count is similar to find but instead of the result it will return the number of the documents
E.g db.collectionName.count({"name":"stu"});
Update
Update allow to re-insert a document for a particular _id, the _id cannot be changed and using update you cannot update only a single field of a document, instead the whole document gets re-inserted.
E.g `db.collectionName.update({_id:1}, {field:”value”});`js 1st parameter is “where”, 2nd is the new document.
$set
Use $set to overcome the limitation of update, you can use $set to update only a single field, while keeping rest of the document as it is.
E.g db.collectionName.update({"_id":1}, {$set:{"age":20}});
$inc can be used to directly increment a particular column by one, has same syntax as $set.
$unset
Use it to remove a particular field from documents.
E.g db.collectionName.update({"_id":3},{$unset:{"removeFieldName":1}});
More Operators
$push – adds a scalar to an array
$pop – removes from last use -1 to remove from front
$pull – removes by value
$pushAll – merges to array
$pullAll – takes out everything
$addToSet – add if it it not already there
E.g
db.friends.update( { _id : "Mike" }, { $push : { interests : "skydiving" } } ); db.friends.update( { _id : "Mike" }, { $pop : { interests : -1 } } ); db.friends.update( { _id : "Mike" }, { $addToSet : { interests : "skydiving" } } ); db.friends.update( { _id : "Mike" }, { $pushAll: { interests : [ "skydiving" , "skiing" ] } } );
Upsert
When you want to update if document exists, otherwise add a new document. Use {$upsert:true}
as the third argument to update method.
Update multiple documents
Pass {multi:true}
to update, to updated multiple documents
E.g db.scores.update({"score":{$lt:70}},{$inc:{"score":20}}, {multi:true});
remove method, is similar to update in syntax but is used to remove documents.
Usually a mongo client will take care of all of the things above, but it is handy to know some of the common operations, so that you can quickly manipulate some data, specially you are just trying out some ideas.