MongoDB: Step-3: Mongo Client Commands
Step3-Mongo Client commands
Introduces you to Mongo-Shell and the most commonly used Mongo commands.
Mongo Shell
Mongo Shell is a javascript interpreter that interactively connects to the mongo server and helps you interactively talk to your mongo server. i.e. the command on it does not finish but you can write the next command which can use the scripting set before it.
The shell is therefore used to
- Connect to MongoDB and fire the DML queries
- Do administrative tasks
Connecting without specifying a database
If you connect to mongo without specifying the database your will land in the test database
Customizing the shell prompt
You can reset the value of the prompt variable
prompt=”prompt>>”
Display your current database
db
Get the current database version
db.version()
Get help with all options on db
db.help()
Displays all the options on db command
List other databases
show databases
or
show dbs
Create a new database
Use <non-existing-database>
use trainingDB1
Switching to different database
use trainingDB
Creating a collection
A collection is similar to a table in RDBMS.
db.emp.insert({“_id”:1, “fname”:”John”, “lname”:”Smith”})
Listing all the data in the collections
db.emp.find({})
Finding all matching data
Let's add some more data
db.emp.insert({“_id”:1, “fname”:”John”, “lname”:”Doe”})
db.emp.insert({“_id”:1, “fname”:”Joseph”, “lname”:”King”})
db.emp.find({“fname”:”John”})
Finding anyone matching data
db.emp.findOne({“fname”:”John”})
Finding matching data with more than one criteria
db.emp.findOne({“fname”:”John”, “lname”:”Doe”})
Primary Key
_id is a mandatory attribute for every mongo document. You can specify your custom value for _id. You can use any data type for _id. You cannot use array for _id.
db.emp.insert({ “fname”:”Jack”, “lname”:”Jill”})
Here since we did not provide a custom _id value, mongo provided its own _id value of the type ObjectId
ObjectId internally stores the timestamp, so when a new document is created, it is appended at the end and mongo does not spend time in finding the correct place for insertion. Using ObjectId() as the _id speeds up the inserts. But using a custom unique value as the _id can speed up the reads though.
ObjectId
Object() is a function in mongo shell that will give you a new ObjectId every time and you can query the ObjectId to give you the timestamp when it was created
ObjectID()
Full Update
prompt> db.<collection>.update(<matching-query>, <update>,<optional-options>)
db.emp.update({“fname”:”John”},{“dept”:10})
Observe:
- The update only updated one document randomly though 2 documents match the query criteria
- The update actually slapped the new document over the old one removing the other attributes already present. So this is not an incremental update it is an override update
db.emp.update({“fname”:”John”},{“dept”:10}, true)
Incremental update — Add a new attribute to an existing document
db.emp.update({“fname”:”John”},{$set:{“dept”:10}})
Observe:
- This time the dept attribute got added to the existing document. It was not a full replacement of the document
Incremental update — Remove the attribute from the existing document
db.emp.update({“fname”:”John”},{$unset:{“dept”:10}})
Updating many documents
db.emp.updateMany({“fname”:”John”},{$set:{“dept”:10}})
All documents matching the query are updated to have the new attribute dept
Array — Push
db.emp.update({“fname”:”Joseph”}, {$push:{“Address”:”London”}})
A new array “Address” got created on the fly with the only value “London”.
Another address “India” got added to the existing array.
db.emp.update({“fname”:”Joseph”}, {$push:{“Address”:”India”}})
Push “India” one more time.
db.emp.update({“fname”:”Joseph”}, {$push:{“Address”:”India”}})
The value India got duplicated inside the array
Array — Pull
Remove all addresses of India.
db.emp.update({“fname”:”Joseph”}, {$pull:{“Address”:”India”}})
Array -Add only if value not existing
db.emp.update({“fname”:”Joseph”}, {$pull:{“Address”:”India”}})
This time since India already existed, it did not add another duplicate value
Find Command
The command provides for matching and selecting the required attributes from the collection and returns a cursor.
prompt>db.emp.find({<matching-query>}, {<projection>})
Projection
To display a field as a result, the project value should be 1.
To stop the display of the field, the project value should be 0
_id field is always displayed by default when it is not needed it has to be switched off explicitly with “_id:0", as you will see in the examples to follow.
db.emp.find({“fname”:”John”}, {“_id”: 1})
Observe: It shows only the _id field.
db.emp.find({“fname”:”John”}, {“fname”: 1})
Observe: Shows the fname field only & _id by default
db.emp.find({“fname”:”John”}, {“fname”: 1, “_id”:0})
Observe: Shows only fname field, _id is not displayed
db.emp.find({“fname”:”John”}, {“fname”: 1, “dept”:0, “_id”:0})
Observe: Mongo does not allow mixing of inclusion and exclusion choice for non “_id” fields
Query Criteria operators
$in, $nin, $gt, $lt, $gte,$lte,
Let’s add the address London to all the John records
db.emp.updateMany({“fname”:”John”}, {$push:{“Address”:”London”}})
Using $in
db.emp.find({“Address”: {$in:[“London”]}}, {_id:0})
Using $all
Get records where Address has both India and London
db.emp.find({“Address”: {$all:[“London”, “India”]}}, {_id:0})
Using $nin
Insert one more record with an address as Sweden.
db.emp.insert({“fname”:”Jane”, “Address”: {$push:[“Sweden”]} })
Get all records where the address is not in India or London
db.emp.find({“Address”: {$nin:[“London”, “India”]}}, {_id:0})
Pretty
You can see a pretty format of the document by using the pretty() notation
db.emp.find().pretty()
Adding subDocuments
Let’s insert one subdocument for some additional details
db.emp.update({“fname”:”Jane”}, {$set:{“additionalDetails”: {“qualification”:”MCA”,”passionateAbout”:”innovation” }}})db.emp.update({“fname”:”John”}, {$set:{“additionalDetails”: {”passionateAbout”:”photography” ,“qualification”:”MCA”,}}})
Querying subDocuments using Dot Notation
Get all documents where qualification is MCA
db.emp.find({“additionalDetails.qualification”: “MCA”}, {fname:1, _id:0}).pretty()
db.emp.find({“additionalDetails.passionateAbout”: “innovation”}, {fname:1, _id:0}).pretty()
Querying for Null values
Let’s add one more document
db.emp.insert({“id”:5, “fname”:”Emily”, “additionalDetails”:null})db.emp.find({“additionalDetails”:null},{“fname”:1, additionalDetails:1})
Observe: This got documents where additionalDetails is null & documents which don’t have additionalDetails
Exists Operator for Query
To get only documents where the additionalDetails subDocument does not exist
db.emp.find({“additionalDetails”:{$exists:false}},{“fname”:1, additionalDetails:1})
Observe: Now we get the list of only those documents which don’t exist.
$gt and $lt for date fields
db.emp.insert({“id”:6, ”updatedTime”: ISODate()})
Remove documents
db.emp.remove({“fname”:”Emily”})
ISODate()
This function returns the dateTime in shell
ISODate()
DateTime attribute
Add updateTime to all documents in the DB
db.emp.updateMany({}, {$set: {“updatedTime”: ISODate()}})
db.emp.update({_id: 1}, {$set: {“updatedTime”: ISODate()}})
Display documents after a specific time
db.emp.find({
"updatedTime" : {"$gte": ISODate("2020-01-26T06:30:50.048Z")}
},{fname:1})
Display documents before a specific time
db.emp.find({
"updatedTime" : {"$lt": ISODate("2020-01-26T06:30:50.048Z")}
},{fname:1})
Sort
You can sort the query data using the dot notation
db.emp.find({
"updatedTime" : {"$lt": ISODate("2020-01-26T06:30:50.048Z")}
},{fname:1}).sort({"updatedTime":1})
Observe: We are able to sort on updateTime which is not part of the projected fields. It means the sort worked before the project was worked on.
Limit
You can specify the number of records you need from the query
db.emp.find({
"updatedTime" : {"$lt": ISODate("2020-01-26T06:30:50.048Z")}
},{fname:1}).sort({"updatedTime":1}).limit(1)
Skip
You can skip a few records before you can get the next stream of data. This can be used for pagination on the server-side
db.emp.find({
"updatedTime" : {"$lt": ISODate("2020-01-26T06:30:50.048Z")}
},{fname:1}).skip(1).sort({"updatedTime":1}).limit(1)
Advanced commands
Above was just an introduction to the most commonly used commands. There are a lot more commands at the disposal of mongo. For a detailed glossary of command check docs.mongo.com. The help is elaborate with various examples, easy to grasp & exhaustive.
Aggregate Pipeline
Mongo offers Aggregation via the use of “map-reduce” function and “Aggregation-Pipeline”
The aggregation pipeline is a framework for data aggregation modeled on the concept of data processing pipelines. Documents enter a multi-stage pipeline that transforms the documents into aggregated results.
You can mix, match and repeat several stages to come up with meaningful analytics of the data. Since the advent of the Aggregation Pipeline which is very intuitive, the use of the map-reduce way of aggregation has reduced drastically
Next Step4
All related links
https://medium.com/@sarada.sastri/mongodb-step-1-an-overview-791e4fe861aa
https://medium.com/@sarada.sastri/mongodb-step-2-setting-up-the-server-4b0fad446c3e
https://medium.com/@sarada.sastri/mongodb-step-3-mongo-client-commands-4366b5ef139f
https://medium.com/@sarada.sastri/mongodb-step-4-designing-the-schema-8c91ee947230
https://medium.com/@sarada.sastri/mongodb-step-5-indexes-and-query-performance-optimizations-ed1bf744315b