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

Update with SET Operator: MongoDB

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

test database, names collection

1
2
3
> db.names.find()
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "name" : "Alia" }
{ "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"), "name" : "Bebo" }

update-with-set-operator-mongodb

Related Read: Update Method: MongoDB

Lets update the first document using only update method.

1
2
3
4
5
6
7
8
9
10
> db.names.update({"name": "Alia"}, {"name": "Alia", "age": 25});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{ "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"), "name" : "Bebo" }
{
        "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"),
        "name" : "Alia",
        "age" : 25
}

Everything is ok in this case. But what if you forget to mention the name field in the second argument of update() method.

1
2
3
4
5
6
> db.names.update({"name": "Alia"}, {"age": 25});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{ "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"), "name" : "Bebo" }
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "age" : 25 }

In this case, the name field gets erased. As we did not specify name field in the second parameter of update() method.

Using $set operator

1
2
3
4
5
6
7
8
9
10
> db.names.update({"name": "Bebo"}, {$set: {"age": 25}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "age" : 25 }
{
        "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"),
        "name" : "Bebo",
        "age" : 25
}

Here we make use of document with name as Bebo. Using $set operator we only specify the fields we want to add or update. Need not specify other existing fields in order to retain them.

Update with SET Operator: MongoDB


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

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



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
37
> db.names.update({"name": "Bebo"}, {$set: {"age": 25, "salary": 25}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "age" : 25 }
{
        "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"),
        "name" : "Bebo",
        "age" : 25,
        "salary" : 25
}
 
 
> db.names.update({"name": "Bebo"}, {$set: {"age": 26, "salary": 25}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "age" : 25 }
{
        "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"),
        "name" : "Bebo",
        "age" : 26,
        "salary" : 25
}
 
 
> db.names.update({"name": "Bebo"}, {$set: {"salary": 30}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{ "_id" : ObjectId("53be5d4604cc1cb0a7bfc3c0"), "age" : 25 }
{
        "_id" : ObjectId("53be5d5204cc1cb0a7bfc3c1"),
        "name" : "Bebo",
        "age" : 26,
        "salary" : 30
}

We can update existing field or add a field to the existing document using $set operator and need not to worry about the other fields in the document.

Update Method: MongoDB

Lets learn how to update MongoDB document using update() method.

test database, names collection

1
2
3
4
5
6
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3c4b1a0eddb0a706e4f56"),
        "name" : "Satish",
        "age" : 27
}

Observe the document, with fields name and age. We’ll be illustrating update() method by working on this document.

update-method-mongodb

1
2
3
4
5
> db.names.update({"name": "Satish"}, {"age": 28});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{ "_id" : ObjectId("53c3c4b1a0eddb0a706e4f56"), "age" : 28 }

update() method takes at least 2 arguments. First argument being the condition(WHERE clause in sql) and the second argument being the fields to be updated. Observe that, whatever the fields we specify in the second argument are only retained(along with _id), all other fields will be erased.

1
2
3
4
5
6
7
8
9
> db.names.update({"age": 28}, {"name": "Satish", "age": 28});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3c4b1a0eddb0a706e4f56"),
        "name" : "Satish",
        "age" : 28
}

Now we’ve updated with name as well as age field and it reflects in the document in the collection.

Update Method: MongoDB


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

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



1
2
3
4
5
6
7
8
9
10
> db.names.update({"age": 28}, {"name": "Satish", "age": 28, "salary": 200000});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{
        "_id" : ObjectId("53c3c4b1a0eddb0a706e4f56"),
        "name" : "Satish",
        "age" : 28,
        "salary" : 200000
}

If we want to update/add a new field to the document, we must also specify all other fields we want to retain in the document.

1
2
3
4
5
> db.names.update({"age": 28}, {"salary": 300000});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 
> db.names.find().pretty()
{ "_id" : ObjectId("53c3c4b1a0eddb0a706e4f56"), "salary" : 300000 }

If we forget to specify other fields, then they will be erased(except _id field).