Tuesday, September 5, 2017

MongoDB: Connecting with Node.js

This tutorial demonstrates how to

 

Introduction

There are two popular libraries for connecting to MongoDB from Node.js:
  • Native Mongo Driver
  • Mongoose

Native Mongo Driver, also called node-mongodb-native, has official support from the creators of MongoDB, and the commands it uses are similar to those used in the MongoDB shell.

Mongoose provides an ODM (Object -> Document Mapping) service. This allows the imposition of schemas on our schemaless MongoDB! It also provides field-level validations, which prevents the insertion of unexpected values in a document's fields. Mongoose is built atop Native Mongo Driver.

We will be using the first one in this tutorial. We will create several JS files that reproduce our "Queer Eye for the Straight Guy" database from a previous post.

First, start the MongoDB daemon in a Terminal window, then start the MongoDB Shell in another Terminal window. If the qeftsg database is still present, remove it using the following commands:

use qeftsg
db.cast.drop();

Now we are ready to recreate the database using Node.js!

 

Creating a Node.js Project

Assuming that Node.js and NPM are installed, open a new Terminal window and create a simple project:

mkdir testproject
cd testproject
npm init

After answering several questions, the following package.js file will be created:

{
  "name": "testproject",
  "version": "1.0.0",
  "description": "Demonstrates how to connect to MongoDB with Node.js",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "MongoDB",
    "Node.js"
  ],
  "author": "Mike Klepper",
  "license": "ISC"
}

Now we install the Native Mongo Driver:

npm install mongodb --save

Once this command has finished running, there are two changes to the TestProject folder:

  1. There is a new folder called node_modules
  2. The project.json file has been modified: a "dependencies" section has been added:
{
  "name": "testproject",
  "version": "1.0.0",
  "description": "Demonstrates how to connect to MongoDB with Node.js",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "MongoDB",
    "Node.js"
  ],
  "author": "Mike Klepper",
  "license": "ISC",
  "dependencies": {
    "mongodb": "^2.2.31"
  }
}

 

Connecting to MongoDB

First, create a file called connect.js in the same folder as package.json, and edit it to read:

 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
/**
 * connect.js
 *
 * By: Mike Klepper
 * Date: 3 September 2017
 *
 * This program demonstrates how to connect to MongoDB
 *
 * See blog post on patriot-geek.blogspot.com
 * for instructions.
 */

var MongoClient = require("mongodb").MongoClient;

const DATABASE_NAME = "qeftsg";
const URL = "mongodb://localhost:27017/" + DATABASE_NAME;

MongoClient.connect(URL, onConnected);

function onConnected(err, db)
{
  if(!err)
  {
    console.log("Connected to MongoDB!");
    closeConnection(err, db);
  }
  else
  {
    console.log("Problems connecting to the DB: " + err);
  }
}

function closeConnection(err, db)
{
  console.log("Closing connection");
  db.close();
}

Run the program as follows:

node connect.js
The output indicates that we successfully connected:
Connected to MongoDB!
Closing connection

Great, we've connected to the database!

 

Create

Now let's create the "cast" collection and populate it with the Fab Five. Create a new program called create.js:

  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
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
 * create.js
 * 
 * By: Mike Klepper
 * Date: 3 September 2017
 * 
 * This program creates five records in MongoDB
 * 
 * See blog post on patriot-geek.blogspot.com
 * for instructions.
 */

var MongoClient = require("mongodb").MongoClient;

const DATABASE_NAME = "qeftsg";
const URL = "mongodb://localhost:27017/" + DATABASE_NAME;

var ted = {
 name: "Ted Allen",
 description: "Food and Wine Connoisseur",
 specialties: ["Alcohol", "Beverages", "Food Preparation", "Food Presentation"],
 age: 52,
 contactInfo:
 {
  website: "tedallen.net",
  email: "info@tedallen.net"
 }
};

var carson = {
 name: "Carson Kressley",
 description: "Fashion Savant",
 specialties: ["Clothing", "Fashion", "Personal Styling"],
 age: 47,
 contactInfo:
 {
  website: "carsonkressley.com",
  facebook: "carsonkressley"
 }
};

var kyan = {
 name: "Kyan Douglas",
 description: "Grooming Guru",
 specialties: ["Hair", "Grooming", "Personal Hygiene", "Makeup"],
 age: 47,
 contactInfo:
 {
  instagram: "kyandouglas",
  facebook: "kyandouglasactual"
 }
};

var thom = {
 name: "Thom Filicia",
 description: "Design Doctor",
 specialties: ["Interior Design", "Home Organization"],
 age: 48,
 contactInfo:
 {
  facebook: "thomfiliciainc",
  email: "info@thomfilicia.com",
  website: "thomfilicia.com"
 }
};

var jai = {
 name: "Jai Rodriguez",
 description: "Culture Vulture",
 specialties: ["Popular Culture", "Relationships", "Social Interaction"],
 age: 38,
 contactInfo:
 {
  website: "myspace.com/jairodriguezmusic",
  facebook: "JaiRodriguezfanpage"
 }
};

MongoClient.connect(URL, onConnected);

function onConnected(err, db)
{
  if(!err)
  {
    console.log("Connected to MongoDB!");
    insertCast(db, closeConnection);
  }
  else
  {
    console.log("Problems connecting to the DB: " + err);
  }
}

function insertCast(db, callback)
{
  var cast = db.collection("cast");
  cast.insertMany([ted, carson, kyan, thom, jai], onInsertManyComplete);
  callback(null, db);
}

function onInsertManyComplete(err, result)
{
  if(!err)
  {
    console.log("Inserted " + result.result.n + " documents into the document collection");
    console.dir(result);
  }
  else
  {
    console.log("Problems inserting records: " + err);
  }
}

function closeConnection(err, db)
{
  console.log("Closing connection");
  db.close();
}

We run the program by entering node create.js and it outputs the following:

Connected to MongoDB!
Closing connection
Inserted 5 documents into the document collection
{ result: { ok: 1, n: 5 },
  ops: 
   [ { name: 'Ted Allen',
       description: 'Food and Wine Connoisseur',
       specialties: [Object],
       age: 52,
       contactInfo: [Object],
       _id: [Object] },
     { name: 'Carson Kressley',
       description: 'Fashion Savant',
       specialties: [Object],
       age: 47,
       contactInfo: [Object],
       _id: [Object] },
     { name: 'Kyan Douglas',
       description: 'Grooming Guru',
       specialties: [Object],
       age: 47,
       contactInfo: [Object],
       _id: [Object] },
     { name: 'Thom Filicia',
       description: 'Design Doctor',
       specialties: [Object],
       age: 48,
       contactInfo: [Object],
       _id: [Object] },
     { name: 'Jai Rodriguez',
       description: 'Culture Vulture',
       specialties: [Object],
       age: 38,
       contactInfo: [Object],
       _id: [Object] } ],
  insertedCount: 5,
  insertedIds: 
   [ ObjectID { _bsontype: 'ObjectID', id: [Object] },
     ObjectID { _bsontype: 'ObjectID', id: [Object] },
     ObjectID { _bsontype: 'ObjectID', id: [Object] },
     ObjectID { _bsontype: 'ObjectID', id: [Object] },
     ObjectID { _bsontype: 'ObjectID', id: [Object] } ] }

 

Retrieve

Now let's retrieve the records. Create a new file called retrieve.js and add the following:

 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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
 * retrieve.js
 *
 * By: Mike Klepper
 * Date: 3 September 2017
 *
 * This program retrieves all records in the cast collection
 *
 * See blog post on patriot-geek.blogspot.com
 * for instructions.
 */

var MongoClient = require("mongodb").MongoClient;

const DATABASE_NAME = "qeftsg";
const URL = "mongodb://localhost:27017/" + DATABASE_NAME;

var database = null;
MongoClient.connect(URL, onConnected);

function onConnected(err, db)
{
  if(!err)
  {
    console.log("Connected to MongoDB!");
    database = db;
    findEverybody(db, closeConnection);
  }
  else
  {
    console.log("Problems connecting to the DB: " + err);
  }
}

function findEverybody(db, closeConnection)
{
  var cast = db.collection("cast");
  cast.find({}, {name: 1, age: 1, _id: 0}).toArray(onResultsFound);
}

function onResultsFound(err, docs)
{
  if(!err)
  {
    console.log("Found the following docs:");
    console.dir(docs);
  }
  else
  {
    console.log("Problems retrieving documents: " + err);
  }

  closeConnection(null, database);
}

function closeConnection(err, db)
{
  console.log("Closing connection");
  database.close();
}

Run the program with node retrieve.js and the output is as expected:

Connected to MongoDB!
Found the following records
[ { name: 'Ted Allen', age: 52 },
  { name: 'Carson Kressley', age: 47 },
  { name: 'Kyan Douglas', age: 47 },
  { name: 'Thom Filicia', age: 48 },
  { name: 'Jai Rodriguez', age: 38 } ]
Closing connection

 

Update

To demonstrate how to update a record, we will update Ted's age. Create a file called update.js and add the following to it:

 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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
 * update.js
 *
 * By: Mike Klepper
 * Date: 3 September 2017
 *
 * This program update a record in the cast collection
 *
 * See blog post on patriot-geek.blogspot.com
 * for instructions.
 */

var MongoClient = require("mongodb").MongoClient;

const DATABASE_NAME = "qeftsg";
const URL = "mongodb://localhost:27017/" + DATABASE_NAME;

var database = null;
MongoClient.connect(URL, onConnected);

function onConnected(err, db)
{
  if(!err)
  {
    console.log("Connected to MongoDB!");
    database = db;
    updateTed(db, closeConnection);
  }
  else
  {
    console.log("Problems connecting to the DB: " + err);
  }
}

function updateTed(db, callback)
{
  var cast = db.collection("cast");
  cast.updateOne({name: "Ted Allen"}, {$set: {age: 53}}, onUpdate);
}

function onUpdate(err, result)
{
  if(!err)
  {
    console.log("Updated Ted");
    console.log(JSON.stringify(result, null, 5));
  }
  else
  {
    console.log("Problems updating the DB: " + err);
  }

  closeConnection(null, database);
}

function closeConnection(err, db)
{
  console.log("Closing connection");
  database.close();
}

Run the program with node update.js and the output is:

Connected to MongoDB!
Updated Ted
{
     "n": 1,
     "nModified": 1,
     "ok": 1
}
Closing connection

Then rerun retrieve.js and we see that Ted's age has indeed been set to 53:

Connected to MongoDB!
Found the following records
[ { name: 'Ted Allen', age: 53 },
  { name: 'Carson Kressley', age: 47 },
  { name: 'Kyan Douglas', age: 47 },
  { name: 'Thom Filicia', age: 48 },
  { name: 'Jai Rodriguez', age: 38 } ]
Closing connection

 

Delete

Finally, let's delete Jai from the database. Create delete.js and add the following lines:

 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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
 * delete.js
 *
 * By: Mike Klepper
 * Date: 3 September 2017
 *
 * This program deletes a record from the cast collection
 *
 * See blog post on patriot-geek.blogspot.com
 * for instructions.
 */

var MongoClient = require("mongodb").MongoClient;

const DATABASE_NAME = "qeftsg";
const URL = "mongodb://localhost:27017/" + DATABASE_NAME;

var database = null;
MongoClient.connect(URL, onConnected);

function onConnected(err, db)
{
  if(!err)
  {
    console.log("Connected to MongoDB!");
    database = db;
    deleteJai(db, closeConnection);
  }
  else
  {
    console.log("Problems connecting to the DB: " + err);
  }
}

function deleteJai(db, callback)
{
  var cast = db.collection("cast");
  cast.deleteOne({name: "Jai Rodriguez"}, onDeleted);
}

function onDeleted(err, result)
{
  if(!err)
  {
    console.log("Deleted Jai");
    console.log(JSON.stringify(result, null, 5));
  }
  else
  {
    console.log("Problems deleting document: " + err);
  }

  closeConnection(err, database);
}

function closeConnection(err, db)
{
  console.log("Closing connection");
  database.close();
}

Run it, and the output should be:

Connected to MongoDB!
Deleted Jai
{
     "n": 1,
     "ok": 1
}
Closing connection

 

Conclusion

That's the basics of using Native Mongo Driver. There is much more to the Native Mongo Client, including:

  • Batch operations
  • Cursor management
  • Aggregation pipeline
  • Application performance management

A great source for information and tutorials is the official documentation.

No comments:

Post a Comment