credit: https://www.youtube.com/watch?v=ogtqMXMpTA4
In this post, we’re going to see a few example of CRUD operation in MongoDB
After making sure that mongod
and mongo
are running, go to the dump’s parent directory in a new terminal. And use the command mongorestore dump
. Where dump
is the folder name in which the database dump is present.
There’re two principal commands for creating documents in MongoDB:
There’re other ways as well such as Update
commands. We call these operations, upserts. Upserts occurs when there’re no documents that match the selector used to identify documents.
Although MongoDB inserts ID by it’s own, We can manually insert custom IDs as well by specifying _id
parameter in the insert...()
functions.
To insert multiple documents we can use insertMany()
- which takes an array of documents as parameter. When executed, it returns multiple id
s for each document in the array. To drop the collection, use drop()
command. Sometimes, when doing bulk inserts - we may insert duplicate values. Specifically, if we try to insert duplicate _id
s, we’ll get the duplicate key error
:
db.startup.insertMany([{_id:"id1", name:"Uber"},{_id:"id2", name:"Airbnb"},{_id:"id1", name:"Uber"},]);
MongoDB stops inserting operation, if it encounters an error, to supress that — we can supply ordered:false
parameter. Ex:
db.startup.insertMany([{_id:"id1", name:"Uber"},{_id:"id2", name:"Airbnb"},{_id:"id1", name:"Airbnb"},],{ordered: false});
MongoDB
assigns an _id
field to each document and assigns primary index on it. There’re ways by which we can apply secondary indices as well. By default, MongoDB
creates values for the _id
field of type ObjectID
. This value is defined in BSON
spec and it’s structured this way:
ObjectID (12 bytes HEX string) = Date (4 bytes, a timestamp value representing number of seconds since the Unix epoch) + MAC address (3 bytes) + PID (2 bytes) + Counter (3 bytes)
To apply specific value filters, we can pass specific values to the find()
command. Here is a SQL query:
SELECT * FROM Table1 WHERE name = 'ABC'
which is equivalent to the following in MongoDB
(notice Collection1
for Table1
):
db.Collection1.find({name: 'ABC'})
We can chain count()
to get the number of results, pretty()
to get a readable result. The results can be further narrowed by adding additional parameters:
db.Collection1.find({name: 'ABC', rollNo: 5})
It’s important to notice that these filters are ANDed together, by default. To apply an OR filter, we need to use $or
. These filters will be specified depending upon the structure of the document. Ex: for object attribute name
for an object school
, we need to specify filter like "school.name" = 'AUHS'
We’re using here the DOT notation, by trying to access a nested field name
of a field school
. Also notice that the filters are quoted, without which we’ll get syntax errors.
Equality matches on arrays can be performed:
In the below query:
db.Collection1.find({name: ['ABC','XYZ']})
MongoDB
is going to identify documents by an exact match to an array of one or more values. Now for these types of queries, the order of elements matters, meaning that we will only match documents that have ABC
followed by XYZ
and those are the only 2 elements of the array name
{name:["ABC","GHI","XYZ"]}, {name:["DEF","ABC","XYZ"]}
In the above document, let’s say that we need to get all the documnts where ABC
is the first element. So, we’ll use the below filter:
db.Schools.find({'name.0': 'ABC' })
MongoDB
returns results in batches. To see how many objects are left in a batch, we use objLeftInBatch()
like this:
var c = db.Schools.find();var doc = function() {return c.hasNext()? c.next : null;}c.objLeftInBatch();
To iterate through this batch we can use doc()
that we setup in the above code block. More learning on cursors can be found at https://docs.mongodb.com/
Projection is a handy way of reducing the size of the data returned for any one query. By default MongoDB
returns all fields in all documents for queries. To limit the amount of data that MongoDB
sends to the application, we can include projections in the queries to reduce network overhead and processing requirements by limiting the fields that’re returned in results documents. They’re provided as second argument to the find()
command. Now, if we need to limit our documents so that they just contain a title. We can do that using this db.Schools.find({name:"ABC"},{rollNo:1}).
In the result, _id
is always returned. To exclude it, use db.Schools.find({name: "ABC"},{rollNo: 1, _id: 0}).
. So, to exclude any field, use 0 next to the colon in project query.
We can use comparison operators as well in our queries. Eg: Use db.Schools.find({rollNo: {$gt: 10}})
To find all students having roll number beyond than 10. Notice the [$gt](https://docs.mongodb.com/manual/reference/operator/query/gt/#op._S_gt)
operator. Combine this filter with $lt for getting results beyond roll number 10 and before roll number 50: db.Schools.find({rollNo: {$gt: 10, $lt: 50}})
.
There’re other operators as well: $gte
(greater than, equal to), $lte
(less than, equal to), $ne
(not equal to). One thing to notice about the not equal to ($ne
) operator is that it not only returns documents having value not equal to specified value but also returns documents not having the attribute itself.
MongoDB
because of it’s flexible data model supports operators that allow us to detect the presence of or absence of a given field. This flexibility in terms of data models also extends to the data type of a field value. Because it’s possible although not usually a good idea, to have the same field in a collection have a different type of value from one document to another. These operators are used for finding the existence of elements ($exists
) and data type of the field using the $type
operator.
Like SQL, there’re logical operators such as $and
, $or
, $not
and $nor
. These’re the examples:
db.Schools.find({$and: [{ rollNo: { $gt: 10 }}, { rollNo: { $gt: 50 }}]})
db.Schools.find({$or: [{ rollNo: { $gt: 10 }}, { rollNo: { $gt: 50 }}]})
Now, why there’s an $and
operator when the filters are by default ANDed? Because, in a JSON
document, we cannot have duplicate keys. In the above $and
example, we’re ANDing rollNo
twice. Remember that $and
is used we need to filter data on the same field.
/
in the below regex code means the start and end of the regular expression.^
means start at the beginning of whatever value we’re matching against and match exactly a capital AB..
is the wild card character.*
indicates match any character any number of times\s
means a space character after AB
db.Schools.find({{ name: { $regex: /^AB\s.*/ }}})
These operators are used to work on arrays. For getting matching values from an array ($all
), arrays of a particular size ($size
) and $elemMatch
- which requires all criteria be satisfied within a single element of an array field.
MongoDB
provides 3 ways to update documents.
updateOne()
- the first argument is the filter expression, second specifies the values to be updated
updateMany()
replaceOne()
db.Schools.updateOne({ name: "ABC" }, { $set: { rollNo: 15 } })
There are a couple of update operators. In the above query, $set
operator simply replaces (or adds if not already exists) the value for the field being specified. There are array update operators as well. To apply updates for each array
element, use the $each
. $position
modifies the $push operator to specify the position in the array to add elements.
Sometimes, we might see elements set to NULL. It’s better to remove them altogether using $unset
operator.
db.Schools.updateMany({ name: null }, { $unset: { name: "" } })
Upserts are operations for which, if no document is found matching our filter, we insert a new document — hence the term upsert.
And here we finish second week course notes
Originally published at xameeramir.github.io.