Concepts:
1. Collections - set of documents
2. Document - BSON document with dynamic schema - means that documents in the same collection do not need to have the same set of fields or structure, and common fields in a collection's documents may hold different types of data.
Important mongo shell commands:
use DATABASE_NAME
>show dbs
>show collections
>db.movie.insert({"name":"tutorials point"}) --- will insert a movie document in movie collection.
db.dropDatabase()
>db.createCollection("mycollection")
>db.createCollection("mycol", { capped : true, autoIndexID : true, size : 6142800, max : 10000 } )
>db.COLLECTION_NAME.drop()
>db.COLLECTION_NAME.insert(document)
Query:
>db.COLLECTION_NAME.find()
RDBMS Where Clause Equivalents in MongoDB
To query the document on the basis of some condition, you can use following operations
| Operation | Syntax | Example | RDBMS Equivalent |
| Equality | {:} | db.mycol.find({"by":"tutorials point"}).pretty() | where by = 'tutorials point' |
| Less Than | {:{$lt:}} | db.mycol.find({"likes":{$lt:50}}).pretty() | where likes < 50 |
| Less Than Equals | {:{$lte:}} | db.mycol.find({"likes":{$lte:50}}).pretty() | where likes <= 50 |
| Greater Than | {:{$gt:}} | db.mycol.find({"likes":{$gt:50}}).pretty() | where likes > 50 |
| Greater Than Equals | {:{$gte:}} | db.mycol.find({"likes":{$gte:50}}).pretty() | where likes >= 50 |
| Not Equals | {:{$ne:}} | db.mycol.find({"likes":{$ne:50}}).pretty() | where likes != 50 |
AND condition:
>db.mycol.find({key1:value1, key2:value2}).pretty()
OR condition:
>db.mycol.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
Example:
'where likes>10 AND (by = 'tutorials point' OR title = 'MongoDB Overview')'
>db.mycol.find("likes": {$gt:10}, $or: [{"by": "tutorials point"}, {"title": "MongoDB Overview"}] }).pretty()
Update:
>db.COLLECTION_NAME.update(SELECTIOIN_CRITERIA, UPDATED_DATA)
>db.mycol.update({'title':'MongoDB Overview'},{$set:{'title':'New MongoDB Tutorial'}})
Replace old document with new data:
>db.COLLECTION_NAME.save({_id:ObjectId(),NEW_DATA})
>db.mycol.save(
{
"_id" : ObjectId(5983548781331adf45ec7), "title":"Tutorials Point New Topic", "by":"Tutorials Point"
}
)
Delete:
>db.COLLECTION_NAME.remove(DELLETION_CRITTERIA)
>db.mycol.remove({'title':'MongoDB Overview'})
>db.COLLECTION_NAME.remove(DELETION_CRITERIA,1) -- removes the first match
>db.mycol.remove() - remove all documents in the collection.
Projection: selectively display fields and not all fields of a document.
>db.COLLECTION_NAME.find({},{KEY:1})
>db.mycol.find({},{"title":1,_id:0}) -- will display title and not _id (which is always displayed otherwise)
Limit:
>db.COLLECTION_NAME.find().limit(NUMBER)
Sort: 1 is used for ascending order while -1 is used for descending order.
>db.COLLECTION_NAME.find().sort({KEY:1})
Index: Here key is the name of filed on which you want to create index and 1 is for ascending order. To create index in descending order you need to use -1.
>db.COLLECTION_NAME.ensureIndex({KEY:1})
Aggregation:
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
select by_user, count(*) from mycol group by by_user -- how many tutorials are written by each user (grouped by a user)
There is a list available aggregation expressions.
| Expression | Description | Example |
| $sum | Sums up the defined value from all documents in the collection. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
| $avg | Calculates the average of all given values from all documents in the collection. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
| $min | Gets the minimum of the corresponding values from all documents in the collection. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
| $max | Gets the maximum of the corresponding values from all documents in the collection. | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
| $push | Inserts the value to an array in the resulting document. | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
| $addToSet | Inserts the value to an array in the resulting document but does not create duplicates. | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
| $first | Gets the first document from the source documents according to the grouping. Typically this makes only sense together with some previously applied “$sort”-stage. | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
| $last | Gets the last document from the source documents according to the grouping. Typically this makes only sense together with some previously applied “$sort”-stage. | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
Replication: client application always interact with primary node and primary node then replicate the data to the secondary nodes.
Setting up replica set:
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"
Backup/Restore MongoDB data:
>mongodump
>mongorestore
Sharding - is a solution for
horizontal scaling of mongodb. More shards (which are in turn made up of
replica sets) can be added depending on the load on the system. A shard
key needs to be an indexed key in the collection and should be present in
all documents. The key need not be unique. It is used to identify the
right shard to send the data to for persistence. Within the shard, replica
sets will create copies of the data on replica set member nodes. So
sharding helps in splitting the data based on a shard key in the document.
Its like storing data in a hashmap. The better the key selection, the
better the data will be divided among the shards.
Sharding is controlled via
mongos router. Application connects to the mongos router which will listen
to the 27017 port for example, and will know based on the shard key on
which shard to insert the data to. For read/find operation mongos will
query the primary node (of the replica set) in each shard and collate the
result.
Liked:
- Easy to setup and develop
against in multiple languages, like Java, python etc. Good to build POC
applications.
- Stable enough.
- Querying is very powerful.
- Pretty performant in querying
and inserts. If the schema has embedded documents mostly then it is worth
using it.
- JSON structures can model
quite complex objects.
- Schema-less DB can be useful
(at least it appears to be so in theory) as it can reduce the pain in
migration, though you still need to write the migration scripts
nevertheless but not have to worry about alter-ing the schema (as there is
no DDL or schema definition in MongoDB, all schema gets realized at
runtime and documents within the same collection can be quite dissimilar).
Disliked:
- By design, no referential
integrity is supported:
- So no cascade
deletion - we need to handle it in application.
- Very hard to design with only
embedded documents in the schema. Most of the time we end up with having
documents with References or links which is akin to relations in the
RDBMS. This comes at a price that to build a transaction with rollback is
too much work in the application. MongoDB only guarantees atomicity within
a document's boundary. So when you have too most documents having
references instead of embedded documents in them then consider using
RDBMS.
- Hard to model many-to-many
relations.