Please read the first guide in this series for more information about MongoDB - Installation, Shell, and Database Management.
You can remove all or few fields from a single record. That's how NoSQL works. For this, we will be using a function called $unset
, which is opposite to the $set
, which we saw before.
The syntax for this is quite tricky. You need to pass the whole object as the second parameter. For example, let's say I don't want that points
field now. Instead I want to remove the points
category from my record. With NoSQL, I just need to execute the following command:
1db.students.update(
2 {
3 name: "Praveen Kumar"
4 },
5 {
6 $unset: {
7 points: ""
8 }
9 }
10);
Here, you can see that it follows the similar structure to $inc
and $set
. Only thing is that you can give any value for the field. Giving ""
or 75
works. Upon executing this, we have the following output:
1> db.students.update({
2... "name": "Praveen Kumar"
3... }, {
4... $unset: {
5... "points" : ""
6... }
7... });
8WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
9> db.students.find({"phone": "9840035007"}).pretty();
10{
11 "_id" : ObjectId("592ebe7e8e61243307417cc4"),
12 "name" : "Praveen Kumar",
13 "degree" : "Cloud Computing MSc",
14 "email" : "[email protected]",
15 "subjects" : [
16 {
17 "name" : "Internet Networks",
18 "prof" : "Prof. Awesome Blossom"
19 },
20 {
21 "name" : "Cloud Computing",
22 "prof" : "Prof. Tech Ninja"
23 },
24 {
25 "name" : "Web Development",
26 "prof" : "Prof. Chunky Monkey"
27 }
28 ],
29 "phone" : [
30 "9840035007",
31 "9967728336",
32 "7772844242"
33 ]
34}
35>
Yippee! We have removed points
from my record.
Upsert is a new term here and it's a combination of update
and insert
. Upserting is similar to saying, "if a record is present, update it, otherwise, insert it." An upsertion occurs when you try to find a match in the database, can't find it, and insert a vlaue instead of simply returning. Let's consider the same example, where we have three records and we'll try to update a non-existent record, say the student "Baahubali".
1db.students.update(
2 {
3 name: "Baahubali"
4 },
5 {
6 name: "Baahubali",
7 degree: "Hill Climbing",
8 email: "[email protected]"
9 }
10);
If we go ahead and run the above command, we get:
1> db.students.update({
2... "name": "Baahubali"
3... }, {
4... "name": "Baahubali",
5... "degree" : "Hill Climbing",
6... "email" : "[email protected]"
7... });
8WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
9>
The result is 0 all across. Doing a simple find()
will give the same results as they were before. If we want the database to check if the match is not found, then insert it, we need to use the option called upsert. Now let's use the same query and make a small change in it. Let's add a third parameter for the update()
function, specifying an object with only upsert
set to true
.
1db.students.update(
2 {
3 name: "Baahubali"
4 },
5 {
6 name: "Baahubali",
7 degree: "Hill Climbing",
8 email: "[email protected]"
9 },
10 {
11 upsert: true
12 }
13);
Executing the above command, we get the following:
1> db.students.update({
2... "name": "Baahubali"
3... }, {
4... "name": "Baahubali",
5... "degree" : "Hill Climbing",
6... "email" : "[email protected]"
7... }, {
8... "upsert": true
9... });
10WriteResult({
11 "nMatched" : 0,
12 "nUpserted" : 1,
13 "nModified" : 0,
14 "_id" : ObjectId("592ffa57962222f55cf0a823")
15})
16>
By setting the upsert
parameter to true
, we can see there's one record inserted (actually upserted) with the _id
returned to us. This is similar to the MySQL Insert query on a table where there is AUTO_INCREMENT
set. Now let's see what's there in the database by making a find()
:
1> db.students.find().pretty();
2{
3 "_id" : ObjectId("592ebe7e8e61243307417cc4"),
4 "name" : "Praveen Kumar",
5 "degree" : "Cloud Computing MSc",
6 "email" : "[email protected]",
7 "subjects" : [
8 {
9 "name" : "Internet Networks",
10 "prof" : "Prof. Awesome Blossom"
11 },
12 {
13 "name" : "Cloud Computing",
14 "prof" : "Prof. Tech Ninja"
15 },
16 {
17 "name" : "Web Development",
18 "prof" : "Prof. Chunky Monkey"
19 }
20 ],
21 "phone" : [
22 "9840035007",
23 "9967728336",
24 "7772844242"
25 ]
26}
27{
28 "_id" : ObjectId("592ed5818e61243307417cc5"),
29 "name" : "Purushothaman",
30 "degree" : "Management",
31 "email" : "[email protected]"
32}
33{
34 "_id" : ObjectId("592ed5818e61243307417cc6"),
35 "name" : "Meaow Meaow",
36 "degree" : "Cat Study",
37 "email" : "[email protected]",
38 "phone" : [
39 "9850420420"
40 ]
41}
42{
43 "_id" : ObjectId("592ffa57962222f55cf0a823"),
44 "name" : "Baahubali",
45 "degree" : "Hill Climbing",
46 "email" : "[email protected]"
47}
48>
Yay! Now Baahubali is in our list of students. (Let's hunt for Kalakeya now! 😁)
Clearly, upsert is a useful function that can save quite a bit of error handling and time down the line.
We have Baahubali as our student, but wait. In those Mahishmati times, they didn't have email, did they? Let's replace his email
field with pigeon
. We have a quick stuff for renaming things in MongoDB. As you guessed, the operator is $rename
. This function is also similar to our $set
function in its syntax, so to rename, it would be:
1db.students.update(
2 {
3 name: "Baahubali"
4 },
5 {
6 $rename: {
7 email: "pigeon"
8 }
9 }
10);
Now when we execute the above command and do a find()
and see the results, we get:
1> db.students.update({
2... "name": "Baahubali"
3... }, {
4... $rename: {
5... "email" : "pigeon"
6... }
7... });
8WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
9> db.students.find({"name": "Baahubali"}).pretty();
10{
11 "_id" : ObjectId("592ffa57962222f55cf0a823"),
12 "name" : "Baahubali",
13 "degree" : "Hill Climbing",
14 "pigeon" : "[email protected]"
15}
16>
Ah! I love this pigeon stuff. We have got one record matched and modified. We have now successfully changed the email
to pigeon
for Baahubali
.
Note to PETA: No pigeons were hurt while writing this article.
We are in the final part of the CRUD (Create Retrieve Update Delete) operation. Make sure that you understand each of the other letters before moving onto deletion.
Deleting records or removing documents is easier as well. We will be using the remove()
function for the removal operation. The function is similar to update()
, but it doesn't take any other parameters except the options
(optional) with justOne
(we will talk about it sooner). Let's try adding a dumb record before trying to delete any of our students.
1> db.students.insert([{"name": "Bleh"}, {"name": "Bleh"}, {"name": "Blah"}]);
2BulkWriteResult({
3 "writeErrors" : [ ],
4 "writeConcernErrors" : [ ],
5 "nInserted" : 3,
6 "nUpserted" : 0,
7 "nMatched" : 0,
8 "nModified" : 0,
9 "nRemoved" : 0,
10 "upserted" : [ ]
11})
12>
Yep, now we have these Blah
and two Bleh
students, who just have their names in them. Let's check the list of students quickly?
1> db.students.find();
2{ "_id" : ObjectId("592ebe7e8e61243307417cc4"), "name" : "Praveen Kumar", "degree" : "Cloud Computing MSc", "..." ] }
3{ "_id" : ObjectId("592ed5818e61243307417cc5"), "name" : "Purushothaman", "degree" : "Management", "email" : "[email protected]" }
4{ "_id" : ObjectId("592ed5818e61243307417cc6"), "name" : "Meaow Meaow", "degree" : "Cat Study", "email" : "[email protected]", "phone" : [ "9850420420" ] }
5{ "_id" : ObjectId("592ffa57962222f55cf0a823"), "name" : "Baahubali", "degree" : "Hill Climbing", "pigeon" : "[email protected]" }
6{ "_id" : ObjectId("59300e628e61243307417cc9"), "name" : "Bleh" }
7{ "_id" : ObjectId("59300e628e61243307417cca"), "name" : "Bleh" }
8{ "_id" : ObjectId("59300e628e61243307417ccb"), "name" : "Blah" }
9>
Oh yes. We have three USOs (Unidentified Student Objects). Let's perform a little cleanup now. The syntax for calling the remove function would be something like this:
1db.students.remove({
2 name: "Blah"
3});
Firing the above command, we are left with:
1> db.students.remove({
2... "name": "Blah"
3... });
4WriteResult({ "nRemoved" : 1 })
5>
Nice, one record has been removed. Let's try the Bleh
as well.
1db.students.remove({
2 name: "Bleh"
3});
The output of the above command shows us:
1> db.students.remove({
2... "name": "Bleh"
3... });
4WriteResult({ "nRemoved" : 2 })
5>
However, it removed all the matches. While right now removing all matches is completely safe, as we know that the Bleh
s are not supposed to be in our list, removing everything can be a problem if we need to check some stuff and remove one entry.
Luckily MongoDB provides a way: the justOne
option. justOne
does the exact thing that we want it to do right now:
justOne
boolean
(optional)To limit the deletion to just one document, set to
true
. Omit to use the default value offalse
and delete all documents matching the deletion criteria.
Let's add two more Bleh
s as before and we'll try this justOne
:
1> db.students.insert([{"name": "Bleh"}, {"name": "Bleh"}]);
2BulkWriteResult({
3 "writeErrors" : [ ],
4 "writeConcernErrors" : [ ],
5 "nInserted" : 2,
6 "nUpserted" : 0,
7 "nMatched" : 0,
8 "nModified" : 0,
9 "nRemoved" : 0,
10 "upserted" : [ ]
11})
12> db.students.find();
13{ "_id" : ObjectId("592ebe7e8e61243307417cc4"), "name" : "Praveen Kumar", "degree" : "Cloud Computing MSc", "email" : "[email protected]", "subjects" : [ { "name" : "Internet Networks", "prof" : "Prof. Awesome Blossom" }, { "name" : "Cloud Computing", "prof" : "Prof. Tech Ninja" }, { "name" : "Web Development", "prof" : "Prof. Chunky Monkey" } ], "phone" : [ "9840035007", "9967728336", "7772844242" ] }
14{ "_id" : ObjectId("592ed5818e61243307417cc5"), "name" : "Purushothaman", "degree" : "Management", "email" : "[email protected]" }
15{ "_id" : ObjectId("592ed5818e61243307417cc6"), "name" : "Meaow Meaow", "degree" : "Cat Study", "email" : "[email protected]", "phone" : [ "9850420420" ] }
16{ "_id" : ObjectId("592ffa57962222f55cf0a823"), "name" : "Baahubali", "degree" : "Hill Climbing", "pigeon" : "[email protected]" }
17{ "_id" : ObjectId("5930132a8e61243307417ccc"), "name" : "Bleh" }
18{ "_id" : ObjectId("5930132a8e61243307417ccd"), "name" : "Bleh" }
19> db.students.remove({
20... "name": "Bleh"
21... }, {
22... "justOne": true
23... });
24WriteResult({ "nRemoved" : 1 })
25> db.students.find();
26{ "_id" : ObjectId("592ebe7e8e61243307417cc4"), "name" : "Praveen Kumar", "degree" : "Cloud Computing MSc", "email" : "[email protected]", "subjects" : [ { "name" : "Internet Networks", "prof" : "Prof. Awesome Blossom" }, { "name" : "Cloud Computing", "prof" : "Prof. Tech Ninja" }, { "name" : "Web Development", "prof" : "Prof. Chunky Monkey" } ], "phone" : [ "9840035007", "9967728336", "7772844242" ] }
27{ "_id" : ObjectId("592ed5818e61243307417cc5"), "name" : "Purushothaman", "degree" : "Management", "email" : "[email protected]" }
28{ "_id" : ObjectId("592ed5818e61243307417cc6"), "name" : "Meaow Meaow", "degree" : "Cat Study", "email" : "[email protected]", "phone" : [ "9850420420" ] }
29{ "_id" : ObjectId("592ffa57962222f55cf0a823"), "name" : "Baahubali", "degree" : "Hill Climbing", "pigeon" : "[email protected]" }
30{ "_id" : ObjectId("5930132a8e61243307417ccd"), "name" : "Bleh" }
31>
What just happened? We inserted two students, both with the same name ("Bleh") to our database. We checked that insertion occurred using find()
. Then we used remove()
with the justOne
attribute to remove a single element with the desired attribute ("name": "Bleh"
).
Thus, the option justOne
helps us to check if we are removing the correct way by limiting to just one of the matched documents.
All this time we have been limited to single-condition querying. What if we need to use multiple conditions? For example, can Bleh
and Blah
be removed in a single command? Well, yes! You have the mighty $or
operator. Let's see how it works by querying stuff.
1db.students.insert([{ name: "Bleh" }, { name: "Blah" }]);
The above command has inserted two different documents, with different name. Let's try to get both of them by using $or
operator. In our find()
method, we need to pass the $or
as an option and add the different objects to be matched as an array:
1db.students.find({
2 $or: [{ name: "Blah" }, { name: "Bleh" }]
3});
Woohoo! Executing the above code, we get both the records now.
1> db.students.find({$or: [{"name": "Blah"}, {"name": "Bleh"}]});
2{ "_id" : ObjectId("593028b68e61243307417cd0"), "name" : "Bleh" }
3{ "_id" : ObjectId("593028b68e61243307417cd1"), "name" : "Blah" }
4>
The next thing is that, we can send this to the remove
function as well and get all our dirt cleared.
1> db.students.remove({$or: [{"name": "Blah"}, {"name": "Bleh"}]});
2WriteResult({ "nRemoved" : 2 })
3> db.students.find();
4{ "_id" : ObjectId("592ebe7e8e61243307417cc4"), "name" : "Praveen Kumar", "degree" : "Cloud Computing MSc", "email" : "[email protected]", "subjects" : [ { "name" : "Internet Networks", "prof" : "Prof. Awesome Blossom" }, { "name" : "Cloud Computing", "prof" : "Prof. Tech Ninja" }, { "name" : "Web Development", "prof" : "Prof. Chunky Monkey" } ], "phone" : [ "9840035007", "9967728336", "7772844242" ] }
5{ "_id" : ObjectId("592ed5818e61243307417cc5"), "name" : "Purushothaman", "degree" : "Management", "email" : "[email protected]" }
6{ "_id" : ObjectId("592ed5818e61243307417cc6"), "name" : "Meaow Meaow", "degree" : "Cat Study", "email" : "[email protected]", "phone" : [ "9850420420" ] }
7{ "_id" : ObjectId("592ffa57962222f55cf0a823"), "name" : "Baahubali", "degree" : "Hill Climbing", "pigeon" : "[email protected]" }
8>
Sweet! That works.
Please continue on to the next guide in this series for more information on MongoDB - Operators.