Creating Unique Key/index: MongoDB

We have learnt how to create a key/index so far – today lets learn how to create unique key/index in MongoDB.

creating-unique-key-index-mongodb

Related Read:
ObjectId ( _id ) as Primary Key: MongoDB
index creation: MongoDB

foo: database name
name: collection name

Primary Key in MongoDB: _id

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> db.name.insert({_id: 1, a: 1});
WriteResult({ "nInserted" : 1 })
 
> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "foo.name" }
 
> db.name.insert({_id: 1, a: 2});
WriteResult({
        "nInserted" : 0,
        "writeError" : {
                "code" : 11000,
                "errmsg" : "insertDocument :: caused by :: 11000 E11000 
                            duplicate key error index: foo.name.$_id_  dup key: { : 1.0 }"
        }
})

Since “_id” is treated as primary key in mongoDB, we can’t insert duplicate values to it. In above case, we are trying to insert value of “_id” as 1 twice – the second time around it threw an error stating the entered value as duplicate.

Related Read:
DBMS Basics: Getting Started Guide
Primary Foreign Unique Keys, AUTO_INCREMENT: MySQL
Primary Key & Foreign Key Implementation: MySQL

Creating Unique Key/index: MongoDB


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

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



Creating Key/Index

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> db.name.insert({a: 1});
WriteResult({ "nInserted" : 1 })
 
> db.name.find()
{ "_id" : ObjectId("53d8cadbbbfe6d81d0bcc364"), "a" : 1 }
{ "_id" : 1, "a" : 1 }
 
> db.name.ensureIndex({a: 1});
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "foo.name" }
{ "v" : 1, "key" : { "a" : 1 }, "name" : "a_1", "ns" : "foo.name" }

Here we create index on field “a”.

Inserting duplicate values into key field

1
2
3
4
5
6
7
> db.name.insert({a: 1});
WriteResult({ "nInserted" : 1 })
 
> db.name.find()
{ "_id" : ObjectId("53d8cadbbbfe6d81d0bcc364"), "a" : 1 }
{ "_id" : 1, "a" : 1 }
{ "_id" : ObjectId("53d8cb4dbbfe6d81d0bcc365"), "a" : 1 }

insert operation simply inserts the duplicate value to field “a” even though its made as a key/index.

Removing documents and Key/Index on field “a”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> db.name.find()
{ "_id" : ObjectId("53d8cadbbbfe6d81d0bcc364"), "a" : 1 }
{ "_id" : 1, "a" : 1 }
{ "_id" : ObjectId("53d8cb4dbbfe6d81d0bcc365"), "a" : 1 }
 
> db.name.remove({a: 1});
WriteResult({ "nRemoved" : 3 })
 
> db.name.find()
 
> db.name.dropIndex({a: 1});
{ "nIndexesWas" : 2, "ok" : 1 }
 
> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "foo.name" }

Before implementing unique key on field “a” we need to first remove the duplicate entries present inside our collection orelse it’ll through errors. Here we also remove the index/key on “a”, so that we can create unique key/index on “a”.

Creating Unique key/index on field “a”

1
2
3
4
5
6
7
> db.name.ensureIndex({a: 1}, {unique: true});
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

To create unique key/index, we need to make use of ensureIndex() method – first parameter being the field name to be made as unique key along with it’s value 1 or -1. 1 signifies ascending order, -1 signifies descending order. The second parameter {unique: true}, specifies that the key/index must be unique key/index, like that of “_id”.

Duplicate key error on our Unique Key!

1
2
3
4
5
6
7
8
9
10
11
12
> db.name.find()
{ "_id" : ObjectId("53d8cb85bbfe6d81d0bcc366"), "a" : 1 }
 
> db.name.insert({a: 1});
WriteResult({
        "nInserted" : 0,
        "writeError" : {
                "code" : 11000,
                "errmsg" : "insertDocument :: caused by :: 11000 E11000 
                            duplicate key error index: foo.name.$a_1  dup key: { : 1.0 }"
        }
})

Now if we try to insert duplicate values into field “a” it throws duplicate key error.

Relationship Between Collections/Tables: MongoDB

In this video tutorial we shall learn about normalization, and the way mongoDB handles relationship between two collections(Primary Key and Foreign Key concept in RDBMS)

Normalization: It refers to the process of organizing the data to minimize redundancy and dependency.

There is no 1 way of doing this in mongoDB. You could implement it according to the needs of your application.

For Example, Normalization is good in the application wherein we do more of write operation. De-normalization is good, wherein we only read.

In today’s tutorial, we shall see how we can implement relationship between two collections/tables and query the database using this relationship.

Database name: company
Collections: info, ceo

mongoDB-database-collection

info 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
>use company
switched to db company
 
>db.info.find().forEach(printjson)
{
"_id" : ObjectId("517e829d005b19f1f0d96b25"),
"name" : "Apple",
"product": "iPhone5S",
"emp_no" : 100
}
 
{
"_id" : ObjectId("517e8377005b19f1f0d96b26"),
"name" : "Technotip",
"product": "Video Tutorials - Educational",
"emp" : [
"Satish",
"Kiran"
],
"Videos" : {
"mongo" : "MongoDB Videos",
"php": "PHP Video Tutorials"
}
}

Create another collection ceo and insert a document

1
2
3
4
5
6
7
8
9
10
>db.ceo.insert({
      name      : "SATISH",
      company_id: db.info.find()[1]._id
});
>db.ceo.find().forEach(printjson)
{
        "_id" : ObjectId("51822e2c60e925795355fd26"),
        "name" : "SATISH",
        "company_id" : ObjectId("517e8377005b19f1f0d96b26")
}

Here we store the _id value present in the second record of info collection inside first record’s company_id field of ceo collection.
This way we build a relation between two collections info and ceo.

Next, we query mongoDB to get some results based on this relationship.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> db.info.find({ _id: db.ceo.find()[0].company_id }).forEach(printjson)
{
        "_id" : ObjectId("517e8377005b19f1f0d96b26"),
        "name" : "Technotip",
        "product" : "Video Tutorials - Educational",
        "emp" : [
                "Satish",
                "Kiran"
        ],
        "videos" : {
                "mongo" : "MongoDB Videos",
                "php" : "PHP Video Tutorials"
        }
}
>

This command(in first line) retrieves the document in the ‘info’ collection which matches the company_id value present in ceo collection and _id of info collection.

Primary Key and Foreign Key Concept in MongoDB


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

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



Note: In traditional database systems(RDBMS) we accomplish the same by using primary key and foreign key concept. And make use of JOINS (Equi JOIN, RIGHT JOIN, LEFT JOIN) to query the database, which actually consumes more time and resources. In mongoDB, there is no need of JOIN’s and hence is faster than RDBMS.

ObjectId ( _id ) as Primary Key: MongoDB

In this video tutorial we shall learn more about ObjectId( _id ) of MongoDB document.

ObjectId is a primary key in any mongoDB document.
We can’t change document id once it has been created and inserted.
If we do not explicitly assign value to _id, then it’ll be automatically assigned and inserted.
We can’t have same document id for more than 1 document.

These ObjectId’s are of BSON datatype.
It’s a 12-byte value.

Basically, each _id is a combination of ..
– Time the document/record was saved/inserted
– Host name of the machine/server it’s running on
– Process id of the server process
– and a random incremental number

Example documents

mongoDB-collection-document

Since the ObjectId‘s are formed taking time of insertion of document into consideration, we can extract this time using getTimestamp() method.

1
db.info.find()[0]._id.getTimestamp()

Custom _id values
We can explicitly define the _id value and in such case system won’t add it for us.

1
2
3
4
5
db.info.insert({
   _id    : 2,
   name   : "Google",
   product: "Google Glass"
})

output

1
2
3
4
5
6
>db.info.find().forEach(printjson)
{
"_id"    : 2,
"name"   : "Google",
"product": "Google Glass"
}

If you insert ObjectId yourselves, then having a separate ‘document_created_at’ field becomes necessary depending on your application requirements.

For that, you can use a inbuilt method Date()

1
2
> new Date()
ISODate("2013-05-01T07:55:12.467Z")

Date is actually a class, but it calls upon the constructor method, hence returning current system/server timestamp, in ISO format.

Remove / Delete / Drop Document

1
db.info.remove({ _id: 2 })

To remove a document, simply pass in a unique { key: value } pair and the document gets deleted/removed.

Primary Key in MongoDB: ObjectId


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

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



Navigation of Documents
To navigate between documents, use the index numbers, and to select particular field use it’s key name.

To get the _id of first document

1
db.info.find()[0]._id

0 is the index of first document or record. _id is the field/key name.

Create and Insert Documents: MongoDB

In this video tutorial, we’ll look at the basic differences between MongoDB and traditional Database Management Systems. Also, commands to create database, collection, documents – insertion.

Topic of discussion:
Key differences.
Keyword differences.
Schema-free collection.
Database creation.
Creation of Collection.
Insertion of Documents.
JavaScript Console/Shall.

Some Commands

Show Database Already Present

1
show dbs

Create Database

1
use company

In MongoDB, it’ll never actually create any database or collection until we start storing documents in it!

Point object ‘db’ to our new database, by switching to company database

1
2
3
4
>use company
Switched to db company 
>db
company

Naming our Collection

1
db.info

So our collection name is info

Number of documents present

1
db.info.count()

using count() method, we check the no of documents present inside info collection.

Inserting document into Collection

1
2
3
4
5
db.info.insert({
 name     : 'Apple',
 product  : 'iPhone5S',
 emp_no   : 100
});

This inserts our first record.
insert() is the method, which accepts key-value pair object as it’s parameter.

JavaScript Shall
Since, this is a JavaScript shall, we can write any valid JavaScript code and interact directly with MongoDB.

Lets see another method to insert documents into the same collection.

Using save method

1
2
3
4
5
6
7
8
9
>var data = {}
>data.name = 'Technotip IT Solutions'
>data.product = 'Video Tutorials - Educational'
>data.emp = [ 'Satish', 'Kiran' ]
>data.videos = {}
>data.videos.mongo = 'MongoDB videos'
>data.videos.php = 'PHP Video Tutorials'
 
>db.info.save(data);

We create a JSON object data.
We start storing { key: value } pair into it.
emp is an array, which contains name of 2 employees.
videos is a sub object.

Now using save method we insert this data object into info collection.

Save()
Save() is a higher lever method. It checks to see if the object we’re inserting is already present in our collection, by checking the _id value we’re inserting. _id field(which is a primary key in MongoDB document)
– If there is no matching _id field in a document, it’ll call insert method and insert the data. And if the data being entered has no _id value, insert() method will create _id value for us, and insert the data into the collection.
– If _id matches to any document in our collection, it’ll use update() instead to update the previously present data with the new data entered by the user.

Database, Collections, Documents: MongoDB


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

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



Note:
There is no Schema for our collection. i.e., no column name and datatype.
Since documents are in BSON format, insertion and finding data is much faster.

Schema-free design is flexible and is of much use in modern day web application.

Example: Users upload photos and tag names of people in the pic. This can be stored as an array of tags in a key value pair, for only those pics which has tags. For other pics, we need not create this array itself. This is flexible. Also BSON format helps create application with high Scalability.

Primary Key & Foreign Key Implementation: MySQL

This video tutorial illustrates the implementation of Primary key and Foreign key, using MySQL.

You can run the same commands / Queries shown in the video on both phpmyadmin as well as on MySQL console.

You can also look at: Primary Foreign Unique Keys, AUTO_INCREMENT: MySQL

student-enrol-database-tables-structure

Primary Key
The PRIMARY KEY constraint uniquely identifies each record in a database table.
Primary keys have unique values.
Primary Keys are NOT NULL by default.

Creating student table:

1
2
3
4
5
6
CREATE TABLE student(
 stud_id  int AUTO_INCREMENT,
 name     varchar(30) NOT NULL,
 age      int NOT NULL,
 PRIMARY KEY(stud_id)
);

Foreign Key
A FOREIGN KEY in one table points to a PRIMARY KEY in another table.

Creating enrol table:

1
2
3
4
5
6
CREATE TABLE enrol(
 rol_no  int AUTO_INCREMENT,
 stud_id int NOT NULL,
 PRIMARY KEY(rol_no),
 FOREIGN KEY(stud_id) REFERENCES student(stud_id)
);

student-enrol-database-tables

Primary Key & Foreign Key Implementation: MySQL


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

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



Note:
1. You can have only 1 primary key per table. But can have zero or more foreign keys in a table.
2. You can not delete primary key row directly, without deleting all the rows referring to that row.