Part 1 - Going deeper into MongoDB
I've been using MongoDB
for quite some time on and off but I always resort to Google every time I've to use it. I now have a use-case where just the basics won't get me far and I'll have to understand the underlying tech to take advantage of it.
Trying it and installing #
Since I just want to try it out, using a Docker image makes perfect sense. No installation required and hence no clean-up too.
docker container run --name mongo mongo
This will start the docker container (name mongo
) which will have the MongoDB
installed. To use the mongo shell I'll open another terminal instance and just exec
or ssh into the above container.
docker exec -it mongo /bin/bash
root@46abee94ab0c:/# mongo
MongoDB shell version v4.4.2
# rest of the startup logs omitted for brevity
>
Wow, we're in!
Before we dive into the shell and try commands, lets take a brief look into whats and whys of MongoDB
NoSQL database #
MongoDB
is a nosql database. That means that there're no tables, rows or foreign key relationships in quite the same manner they are in relational databases like MySQL
etc.
It's a document store, which means you can store documents inside it directly. A document
doesn't mean a literal file here. It means a JSON
object.
{ "name": "Jonas Kahnwald" }
Above is an example of a document.
In a SQL database, data is stored in a table
and a table is made of rows
. Each row has a fixed number of columns.
Similarly, in NoSQL database, the data is stored in collections
, where each collection is made of documents
. There's no restriction that each document should contain the same attributes or columns as in a relational database.
So this can be done in a NoSQL DB like MongoDB
[{ "name": "Jonas Kahnwald" }, { "favouriteFood": "Croissants" }]
Not that I'm recommending of doing this (having disjoint attribute names for every document) but you can do it.
The benefit of this is in future if your data model changes, you can change the document structure without migrating the old data.
showing co-relations between a SQL and a NoSQL database
mongo shell #
As shown above the shell of MongoDB isn't just like a regular database shell. It can even run JavaScript inside it.
> 0.1 + 0.2
0.30000000000000004
LOL, the best way to test JS
By default when you connect to a Mongo Shell
and don't specify a db name, it connects to test
.
You can check this by typing db and seeing the value.
> db
test
>
You can access all the collections, documents from the keyword db
. It holds the currently selected database.
Operations (CRUD) #
create #
Since the database is empty, I'll start by adding something to it.
- create a collection (empty)
- add a document inside it using
insertOne
- done!
# create an empty collection - food
> db.food
test.food
# create a document inside the food collection
# db.food makes sure the document is
# added inside the `food` collection
> db.food.insertOne({name: 'Croissant'})
{
"acknowledged" : true,
"insertedId" : ObjectId("5fd64dabed36a5727cf5a243")
}
There's another method insertMany
which as you correctly guessed inserts multiple documents in one go.
> db.food.insertMany([{name: "Samosa"}, {name: "Jalebi"}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5fd64f09016e04b26b6fbfa9"),
ObjectId("5fd64f09016e04b26b6fbfaa")
]
}
>
read #
There are two methods to read.
- findOne
- find (for finding all documents)
> db.food.findOne()
{ "_id" : ObjectId("5fd64dabed36a5727cf5a243"), "name" : "Croissant" }
> db.food.find()
{ "_id" : ObjectId("5fd64dabed36a5727cf5a243"), "name" : "Croissant" }
{ "_id" : ObjectId("5fd64f09016e04b26b6fbfa9"), "name" : "Samosa" }
{ "_id" : ObjectId("5fd64f09016e04b26b6fbfaa"), "name" : "Jalebi" }
>
I can also pass a search criteria to find a particular document too.
> db.food.find({ name: "Samosa" })
{ "_id" : ObjectId("5fd64f09016e04b26b6fbfa9"), "name" : "Samosa" }
update #
This will be covered in part 2, something for you to comeback and subscribe.
genius skills for making you subscribe and bookmark :P
delete #
Again, there are two ways you can delete
- deleteOne
- deleteMany
You can pass a matching criteria and all the records will get deleted that fit the criteria with deleteMany
> db.food.deleteMany({name: "Samosa"})
{ "acknowledged" : true, "deletedCount" : 1 }
You don't believe me?
> db.food.find()
{ "_id" : ObjectId("5fd64dabed36a5727cf5a243"), "name" : "Croissant" }
{ "_id" : ObjectId("5fd64f09016e04b26b6fbfaa"), "name" : "Jalebi" }
I told you!
Bonus #
- If you'd have noticed, I'm sure you'd have that a special attribute
_id
gets added to each record. If you pass it yourself, it'll be honoured else Mongo will create one for you. No two records can have the same_id
. I think that was obvious and I could've saved those free extra keystrokes, but I'm nice :P - Since all is JavaScript, you can just write the name of the function to see what it does
> db.food.insertOne
function(document, options) {
var opts = Object.extend({}, options || {});
// Add _id ObjectId if needed
document = this.addIdIfNeeded(document);
// Get the write concern
var writeConcern = this._createWriteConcern(opts);
// Result
var result = {acknowledged: (writeConcern && writeConcern.w == 0) ? false : true};
// Use bulk operation API already in the shell
var bulk = this.initializeOrderedBulkOp();
bulk.insert(document);
# removed rest for brevity
OMG! I know right!
See you in the next part. Kbye