Multi-Update: MongoDB

Lets learn how to update all the documents present in a collection using update() method, using the option multi: true

multi update mongodb

test database, names collection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
> db.names.find().pretty()
{
        "_id" : ObjectId("53c6392a2eea8062e084cb57"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1
}
{
        "_id" : ObjectId("53c639392eea8062e084cb58"),
        "Company" : "Apple",
        "Product" : "Mac",
        "No" : 2
}
{
        "_id" : ObjectId("53c63b26b003603dfdcf8c52"),
        "Company" : "Xiaomi",
        "Product" : "Mi3",
        "No" : 3
}
{
        "_id" : ObjectId("53c63bd1b003603dfdcf8c53"),
        "Product" : "Smart Watch",
        "No" : 4,
        "Company" : "Sony"
}

We have 4 documents in “names” collection.

find() method

1
2
3
4
5
> db.names.find({}, {"Company": 1, "_id": 0}).pretty()
{ "Company" : "Google" }
{ "Company" : "Apple" }
{ "Company" : "Xiaomi" }
{ "Company" : "Sony" }

If we leave the first argument of find() method empty, it matches with all the documents of the collection. Hence it fetched all the Company names from the documents.

Multi-Update: MongoDB


[youtube https://www.youtube.com/watch?v=yuVBs4hcYOQ]

YouTube Link: https://www.youtube.com/watch?v=yuVBs4hcYOQ [Watch the Video In Full Screen.]



update() method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
> db.names.update({}, {$set: {"IT": "true"}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c6392a2eea8062e084cb57"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1,
        "IT" : "true"
}
{
        "_id" : ObjectId("53c639392eea8062e084cb58"),
        "Company" : "Apple",
        "Product" : "Mac",
        "No" : 2
}
{
        "_id" : ObjectId("53c63b26b003603dfdcf8c52"),
        "Company" : "Xiaomi",
        "Product" : "Mi3",
        "No" : 3
}
{
        "_id" : ObjectId("53c63bd1b003603dfdcf8c53"),
        "Product" : "Smart Watch",
        "No" : 4,
        "Company" : "Sony"
}

But in case of update() method, if the first argument is left empty, it randomly matches to only 1 document in the collection.

Related Read: Update with SET Operator: MongoDB

unset the IT field

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
> db.names.update({"IT": {$exists: true}}, {$unset: {"IT": "true"}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c6392a2eea8062e084cb57"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1
}
{
        "_id" : ObjectId("53c639392eea8062e084cb58"),
        "Company" : "Apple",
        "Product" : "Mac",
        "No" : 2
}
{
        "_id" : ObjectId("53c63b26b003603dfdcf8c52"),
        "Company" : "Xiaomi",
        "Product" : "Mi3",
        "No" : 3
}
{
        "_id" : ObjectId("53c63bd1b003603dfdcf8c53"),
        "Product" : "Smart Watch",
        "No" : 4,
        "Company" : "Sony"
}

Here we select the document which has a field called “IT” and remove it from that document.

Related Read:
$exists, $type, $regex operators: MongoDB
Update with UNSET Operator: MongoDB

multi-update true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
> db.names.update({}, {$set: {"IT": "true"}}, {multi: true});
WriteResult({ "nMatched" : 4, "nUpserted" : 0, "nModified" : 4 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c6392a2eea8062e084cb57"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1,
        "IT" : "true"
}
{
        "_id" : ObjectId("53c639392eea8062e084cb58"),
        "Company" : "Apple",
        "Product" : "Mac",
        "No" : 2,
        "IT" : "true"
}
{
        "_id" : ObjectId("53c63b26b003603dfdcf8c52"),
        "Company" : "Xiaomi",
        "Product" : "Mi3",
        "No" : 3,
        "IT" : "true"
}
{
        "_id" : ObjectId("53c63bd1b003603dfdcf8c53"),
        "Product" : "Smart Watch",
        "No" : 4,
        "Company" : "Sony",
        "IT" : "true"
}

Here we have 3 arguments for update() method. First one is intentionally left empty. In second argument, we specify the changes needed to the documents. In third argument we specify the option, multi: true – which tells mongo engine to match with all the documents in the collection.

Update with upsert: MongoDB

Lets learn to use upsert option with update() method.

upsert basically inserts document into the collection, if there is no matching document found in the collection. If there is a match found, then the document simply gets updated – in which case upsert option will not have any effect on the selected document.

update with upsert mongodb

test database, names collection

1
2
3
4
5
6
7
8
9
10
11
12
13
> db.names.find().pretty()
{
        "_id" : ObjectId("53c6392a2eea8062e084cb57"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1
}
{
        "_id" : ObjectId("53c639392eea8062e084cb58"),
        "Company" : "Apple",
        "Product" : "iPhone",
        "No" : 2
}

There are 2 documents inside “names” collection, with _id, Company, Product and No as its fields.

Update with upsert: MongoDB


[youtube https://www.youtube.com/watch?v=ZQjNHjVv_W8]

YouTube Link: https://www.youtube.com/watch?v=ZQjNHjVv_W8 [Watch the Video In Full Screen.]



update() method, with $set operator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> db.names.update({"Company": "Apple"}, {$set: {"Product": "Mac"}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c6392a2eea8062e084cb57"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1
}
{
        "_id" : ObjectId("53c639392eea8062e084cb58"),
        "Company" : "Apple",
        "Product" : "Mac",
        "No" : 2
}

We select second document using “Company” – “Apple“. Here, the “Product” field value gets updated from iPhone to Mac.

Related Read: Update with SET Operator: MongoDB

No Match Found for Updation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> db.names.update({"Company": "Xiaomi"}, {$set: {"Product": "Mi3", "No": 3}});
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c6392a2eea8062e084cb57"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1
}
{
        "_id" : ObjectId("53c639392eea8062e084cb58"),
        "Company" : "Apple",
        "Product" : "Mac",
        "No" : 2
}

Since, there is no matching “Company” called Xiaomi in “names” collection, there will be no matching document, hence no modification of document.

updation with upsert option

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
> db.names.update({"Company": "Xiaomi"}, 
                  {$set: {"Product": "Mi3", "No": 3}},
                  {upsert: true});
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 1,
        "nModified" : 0,
        "_id" : ObjectId("53c63b26b003603dfdcf8c52")
})
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c6392a2eea8062e084cb57"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1
}
{
        "_id" : ObjectId("53c639392eea8062e084cb58"),
        "Company" : "Apple",
        "Product" : "Mac",
        "No" : 2
}
{
        "_id" : ObjectId("53c63b26b003603dfdcf8c52"),
        "Company" : "Xiaomi",
        "Product" : "Mi3",
        "No" : 3
}

Observe the 3rd argument of update() method – upsert: true. In this case, since there is no matching document found inside the “names” collection, for “Company” Xiaomi, it inserts the document with all the fields and values specified in the update command. i.e., Company: Xiaomi, Product: Mi3, No: 3

unintentional modification of data with upsert

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
> db.names.update({"No": {$gt: 3}}, 
                  {$set: {"Product": "Glass", "No": 4}}, 
                  {upsert: true});
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 1,
        "nModified" : 0,
        "_id" : ObjectId("53c63bd1b003603dfdcf8c53")
})
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c6392a2eea8062e084cb57"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1
}
{
        "_id" : ObjectId("53c639392eea8062e084cb58"),
        "Company" : "Apple",
        "Product" : "Mac",
        "No" : 2
}
{
        "_id" : ObjectId("53c63b26b003603dfdcf8c52"),
        "Company" : "Xiaomi",
        "Product" : "Mi3",
        "No" : 3
}
{
        "_id" : ObjectId("53c63bd1b003603dfdcf8c53"),
        "Product" : "Glass",
        "No" : 4
}

We have documents which has values 1, 2 and 3 for the field “No”. But in above command the condition is to select documents which has “No” value above 3 – which results in 0 documents being selected. But since we have “upsert: true” as the third argument of update() method, the “field: value” – “Product: Glass” and “No: 4” gets inserted into the “names” collection. So we need to take proper care of our commands and conditions – so that unintentional insertion of data or document can be avoided.

upsert effect on existing data/document

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
> db.names.update({"No": 4}, 
                  {$set: {"Company": "Sony", "Product": "Smart Watch"}}, 
                  {upsert: true});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c6392a2eea8062e084cb57"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1
}
{
        "_id" : ObjectId("53c639392eea8062e084cb58"),
        "Company" : "Apple",
        "Product" : "Mac",
        "No" : 2
}
{
        "_id" : ObjectId("53c63b26b003603dfdcf8c52"),
        "Company" : "Xiaomi",
        "Product" : "Mi3",
        "No" : 3
}
{
        "_id" : ObjectId("53c63bd1b003603dfdcf8c53"),
        "Product" : "Smart Watch",
        "No" : 4,
        "Company" : "Sony"
}

In this case, there is a document inside the collection which has “No”: 4. So the upsert option will not have any effect on the selected data/document – it simply gets updated with the field values specified in the second argument of update() method. i.e., the document with “No”: 4 is selected and the “Company”: “Sony”, “Product”: “Smart Watch” gets added to the existing document.

Working With Arrays: MongoDB

Lets learn some of the methods and operators to work with arrays in MongoDB.

In this video tutorial, we’ll be looking at:
update()
$set
$push
$pop
$pushAll
$pull
$pullAll
$addToSet

update set push pop pushAll pull pullAll addToSet operators mongodb

test database, names collection

1
2
3
4
5
6
7
8
9
MongoDB shell version: 2.6.1
connecting to: test
> db.names.find()
 
> db.names.insert({"_id": 1, "a": [1, 2, 3, 4]});
WriteResult({ "nInserted" : 1 })
 
> db.names.find()
{ "_id" : 1, "a" : [ 1, 2, 3, 4 ] }

We insert a document into “names” collection. We’ll be working on the array field present in the document.

Working With Arrays: MongoDB


[youtube https://www.youtube.com/watch?v=xc5TiSqvnPQ]

YouTube Link: https://www.youtube.com/watch?v=xc5TiSqvnPQ [Watch the Video In Full Screen.]



update() method

1
2
3
4
5
> db.names.update({"_id": 1}, {"a": [1, 2, 3, 4, 5]});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find()
{ "_id" : 1, "a" : [ 1, 2, 3, 4, 5 ] }

We can update the array by simply using update() method. But here, we need to remember all the elements of the array as well as the new element to be inserted into the array. Thus, this method is somewhat tedious.

$set operator

1
2
3
4
5
> db.names.update({"_id": 1}, {$set: {"a.5": 6}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find()
{ "_id" : 1, "a" : [ 1, 2, 3, 4, 5, 6 ] }

We could insert an element into the array by making use of $set operator. Here we need to know the position where the new element needs to be inserted. In mongoDB, array index starts from zero.

$push operator

1
2
3
4
5
> db.names.update({"_id": 1}, {$push: {"a": 7}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find()
{ "_id" : 1, "a" : [ 1, 2, 3, 4, 5, 6, 7 ] }

using $push operator we can insert an element to the right hand side of the array. Here we simply specify the key and the value/element to be inserted.

$pop: {a: 1}

1
2
3
4
5
> db.names.update({"_id": 1}, {$pop: {"a": 1}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find()
{ "_id" : 1, "a" : [ 1, 2, 3, 4, 5, 6 ] }

$pop operator which has 1 as value to the key, removes the right most element from the array.

$pop: {a: -1}

1
2
3
4
5
> db.names.update({"_id": 1}, {$pop: {"a": -1}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find()
{ "_id" : 1, "a" : [ 2, 3, 4, 5, 6 ] }

$pop operator which has -1 as value to the key, removes the left most element from the array.

$pushAll operator

1
2
3
4
5
> db.names.update({"_id": 1}, {$pushAll: {"a": [7, 8]}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find()
{ "_id" : 1, "a" : [ 2, 3, 4, 5, 6, 7, 8 ] }

$pushAll operator inserts all the elements(array of elements) specified, to the right hand side of the existing array.

$pull operator

1
2
3
4
5
> db.names.update({"_id": 1}, {$pull: {"a": 3}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find()
{ "_id" : 1, "a" : [ 2, 4, 5, 6, 7, 8 ] }

$pull operator pulls or removes the specified element from the array, irrespective of its position.

$pullAll operator

1
2
3
4
5
> db.names.update({"_id": 1}, {$pullAll: {"a": [2, 7, 8]}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find()
{ "_id" : 1, "a" : [ 4, 5, 6 ] }

$pullAll operator pulls/removes all the elements(array of elements) specified from the array, irrespective of its position.

$addToSet operator

1
2
3
4
5
> db.names.update({"_id": 1}, {$addToSet: {"a": 3}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find()
{ "_id" : 1, "a" : [ 4, 5, 6, 3 ] }

$addToSet operator adds specified element to the array, if its not already present in the array. If the element is already present in the array, then it doesn’t add it once again.

1
2
3
4
> db.names.update({"_id": 1}, {$addToSet: {"a": 3}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.names.find()
{ "_id" : 1, "a" : [ 4, 5, 6, 3 ] }

If the element is already present in the array, then $addToSet doesn’t add it once again.

Increment($inc) operator: MongoDB

Lets learn how to use $inc operator with update() method in MongoDB.

inc operator with update

test database, names collection

1
2
3
4
5
6
7
8
9
10
11
12
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3fc2005e0ce2719d91bd2"),
        "Company" : "Google",
        "No" : 1
}
{
        "_id" : ObjectId("53c3fd3bb9ae26fa217b1e12"),
        "Company" : "Apple",
        "Product" : "iPhone",
        "No" : 2
}

Here we have 2 documents. And we’ll be working on first document to illustrate the working of $inc operator.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> db.names.update({"Company": "Google"}, {$inc: {"No": 2}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3fc2005e0ce2719d91bd2"),
        "Company" : "Google",
        "No" : 3
}
{
        "_id" : ObjectId("53c3fd3bb9ae26fa217b1e12"),
        "Company" : "Apple",
        "Product" : "iPhone",
        "No" : 2
}

Here “No” field will be incremented by 2. So the final value of “No” field is 3 (1+2).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> db.names.update({"Company": "Google"}, {$inc: {"Sl_no": 1}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3fc2005e0ce2719d91bd2"),
        "Company" : "Google",
        "No" : 3,
        "Sl_no" : 1
}
{
        "_id" : ObjectId("53c3fd3bb9ae26fa217b1e12"),
        "Company" : "Apple",
        "Product" : "iPhone",
        "No" : 2
}

If we apply $inc operator on an non-existing field, it will be created with the increment value itself.

Increment($inc) operator: MongoDB


[youtube https://www.youtube.com/watch?v=LjJJOY4DLMs]

YouTube Link: https://www.youtube.com/watch?v=LjJJOY4DLMs [Watch the Video In Full Screen.]



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> db.names.update({"Company": "Google"}, {$inc: {"No": 1}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3fc2005e0ce2719d91bd2"),
        "Company" : "Google",
        "No" : 4,
        "Sl_no" : 1
}
{
        "_id" : ObjectId("53c3fd3bb9ae26fa217b1e12"),
        "Company" : "Apple",
        "Product" : "iPhone",
        "No" : 2
}

Here we increment the value of “No” once again by 1. So the final value of “No” field is 4 (3+1).

Update with UNSET Operator: MongoDB

Lets use $unset operator along with update() method, to update the documents.

update with set operator mongodb Update with UNSET Operator: MongoDB

test database, names collection

1
2
3
4
5
6
7
8
9
10
11
12
13
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3fc2005e0ce2719d91bd2"),
        "Company" : "Google",
        "Product" : "Nexus",
        "No" : 1
}
{
        "_id" : ObjectId("53c3fd3bb9ae26fa217b1e12"),
        "Company" : "Apple",
        "Product" : "iPhone",
        "No" : 2
}

Here we have 2 documents with fields _id, Company, Product and No.

Update with UNSET Operator: MongoDB


[youtube https://www.youtube.com/watch?v=8UUdITiZ5ZE]

YouTube Link: https://www.youtube.com/watch?v=8UUdITiZ5ZE [Watch the Video In Full Screen.]



We could remove a field using update() method, by not specifying it in the second argument.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> db.names.update({"No": 1}, {"Company": "Google", "No": 1});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3fc2005e0ce2719d91bd2"),
        "Company" : "Google",
        "No" : 1
}
{
        "_id" : ObjectId("53c3fd3bb9ae26fa217b1e12"),
        "Company" : "Apple",
        "Product" : "iPhone",
        "No" : 2
}

Related Read: Update Method: MongoDB

This way, we could eliminate the field Product. But this is a tedious process – we need to remember all the fields inorder to achieve this. It gets difficult when we have many fields in our document. To solve this problem, we have $unset operator, where we only need to know the field name which we want to remove.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> db.names.update({"No": 1}, {$unset: {"Product": 1}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3fc2005e0ce2719d91bd2"),
        "Company" : "Google",
        "No" : 1
}
{
        "_id" : ObjectId("53c3fd3bb9ae26fa217b1e12"),
        "Company" : "Apple",
        "Product" : "iPhone",
        "No" : 2
}

$unset operator syntax is same to unset or remove array from a document.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
> db.names.update({"No": 1}, {$set: {"Product": ["LG", "Samsung", "HTC"]}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3fc2005e0ce2719d91bd2"),
        "Company" : "Google",
        "No" : 1,
        "Product" : [
                "LG",
                "Samsung",
                "HTC"
        ]
}
{
        "_id" : ObjectId("53c3fd3bb9ae26fa217b1e12"),
        "Company" : "Apple",
        "Product" : "iPhone",
        "No" : 2
}
 
> db.names.update({"No": 1}, {$unset: {"Product": 1}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3fc2005e0ce2719d91bd2"),
        "Company" : "Google",
        "No" : 1
}
{
        "_id" : ObjectId("53c3fd3bb9ae26fa217b1e12"),
        "Company" : "Apple",
        "Product" : "iPhone",
        "No" : 2
}

Related Read: Update with SET Operator: MongoDB