Connecting Node.js to MongoDB
MongoDB is a document-oriented database management system written in C++.
In this section, we will introduce how to connect to MongoDB and perform database operations using Node.js.
If you do not have basic knowledge of MongoDB, you can refer to our tutorial: MongoDB Tutorial.
Installing the Driver
This tutorial uses the custom cnpm command from Taobao for installation:
$ cnpm install mongodb
Next, we will implement the create, read, update, and delete functionalities.
Creating a Database
To create a database in MongoDB, we first need to create a MongoClient object and configure the specified URL and port number.
If the database does not exist, MongoDB will create the database and establish a connection.
Creating a Connection
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/tutorialpro";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
console.log("Database created!");
db.close();
});
Creating a Collection
We can use the createCollection() method to create a collection:
Creating a Collection
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/tutorialpro';
MongoClient.connect(url, function (err, db) {
if (err) throw err;
console.log('Database created');
var dbase = db.db("tutorialpro");
dbase.createCollection('site', function (err, res) {
if (err) throw err;
console.log("Collection created!");
db.close();
});
});
Database Operations (CRUD)
Unlike MySQL, MongoDB automatically creates databases and collections, so we do not need to manually create them before use.
Inserting Data
The following example connects to the database tutorialpro
and the site
collection, and inserts a single data entry using insertOne()
:
Inserting a Single Data Entry
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("tutorialpro");
var myobj = { name: "tutorialpro.org", url: "www.tutorialpro" };
dbo.collection("site").insertOne(myobj, function(err, res) {
if (err) throw err;
console.log("Document inserted successfully");
db.close();
});
});
Executing the following command outputs the result:
$ node test.js
Document inserted successfully
From the output, it is clear that the data has been inserted successfully.
We can also open the MongoDB client to view the data, such as:
> show dbs
tutorialpro 0.000GB # Automatically created the tutorialpro database
> show tables
site # Automatically created the site collection (table)
> db.site.find()
{ "_id" : ObjectId("5a794e36763eb821b24db854"), "name" : "tutorialpro.org", "url" : "www.tutorialpro" }
>
To insert multiple entries, use insertMany()
:
Inserting Multiple Data Entries
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("tutorialpro");
var myobj = [
{ name: 'tutorialpro1.org', url: 'www.tutorialpro1' },
{ name: 'tutorialpro2.org', url: 'www.tutorialpro2' },
{ name: 'tutorialpro3.org', url: 'www.tutorialpro3' }
];
dbo.collection("site").insertMany(myobj, function(err, res) {
if (err) throw err;
console.log("Number of documents inserted: " + res.insertedCount);
db.close();
});
});
Executing the following command outputs the result:
$ node test.js
Number of documents inserted: 3
From the output, it is clear that the data has been inserted successfully.
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("tutorialpro");
var myobj = [
{ name: 'tutorialpro', url: 'https://c.tutorialpro.org', type: 'cn' },
{ name: 'Google', url: 'https://www.google.com', type: 'en' },
{ name: 'Facebook', url: 'https://www.google.com', type: 'en' }
];
dbo.collection("site").insertMany(myobj, function(err, res) {
if (err) throw err;
console.log("Number of documents inserted: " + res.insertedCount);
db.close();
});
});
res.insertedCount is the number of inserted documents.
Query Data
You can use find()
to retrieve data, find()
returns all data that matches the criteria.
If no criteria are specified, find()
returns all data in the collection.
find()
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("tutorialpro");
dbo.collection("site").find({}).toArray(function(err, result) { // Returns all data in the collection
if (err) throw err;
console.log(result);
db.close();
});
});
The following example retrieves instances where the name is "tutorialpro.org":
Query Data with Specific Criteria
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("tutorialpro");
var whereStr = { "name": 'tutorialpro.org' }; // Query criteria
dbo.collection("site").find(whereStr).toArray(function(err, result) {
if (err) throw err;
console.log(result);
db.close();
});
});
Executing the following command outputs the result:
[ { _id: 5a794e36763eb821b24db854,
name: 'tutorialpro.org',
url: 'www.tutorialpro' } ]
Update Data
We can also modify data in the database. The following example changes the url to https://www.tutorialpro.org for the name "tutorialpro.org":
Update a Single Document
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("tutorialpro");
var myquery = { name: "tutorialpro.org" };
var newvalues = { $set: { url: "https://www.tutorialpro.org" } };
dbo.collection("site").updateOne(myquery, newvalues, function(err, res) {
if (err) throw err;
console.log("Document updated");
db.close();
});
});
var whereStr = {"name":'tutorialpro.org'}; // Query condition
var updateStr = {$set: { "url" : "https://www.tutorialpro.org" }};
dbo.collection("site").updateOne(whereStr, updateStr, function(err, res) {
if (err) throw err;
console.log("Document updated successfully");
db.close();
});
After successful execution, check the data modification in the mongo management tool:
> db.site.find().pretty()
{
"_id" : ObjectId("5a794e36763eb821b24db854"),
"name" : "tutorialpro.org",
"url" : "https://www.tutorialpro.org" // Modified to https
}
To update all documents that match the criteria, use updateMany()
:
Update Multiple Documents
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("tutorialpro");
var whereStr = {"type":'en'}; // Query condition
var updateStr = {$set: { "url" : "https://www.tutorialpro.org" }};
dbo.collection("site").updateMany(whereStr, updateStr, function(err, res) {
if (err) throw err;
console.log(res.result.nModified + " documents updated");
db.close();
});
});
result.nModified
indicates the number of documents updated.
Delete Data
The following example deletes the data where name
is "tutorialpro.org":
Delete One Document
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("tutorialpro");
var whereStr = {"name":'tutorialpro.org'}; // Query condition
dbo.collection("site").deleteOne(whereStr, function(err, obj) {
if (err) throw err;
console.log("Document deleted successfully");
db.close();
});
});
After successful execution, check the data deletion in the mongo management tool:
> db.site.find()
>
To delete multiple documents, use the deleteMany()
method:
Delete Multiple Documents
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("tutorialpro");
var whereStr = { type: "en" }; // Query condition
dbo.collection("site").deleteMany(whereStr, function(err, obj) {
if (err) throw err;
console.log("Documents deleted successfully");
db.close();
});
});
console.log(obj.result.n + " documents deleted"); db.close(); }); });
The number of documents deleted is obj.result.n.
### Sorting
Sorting uses the `sort()` method, which accepts a parameter specifying ascending (1) or descending (-1) order.
For example:
{ type: 1 } // Sort by type field in ascending order { type: -1 } // Sort by type field in descending order
Sort by type in ascending order:
## Sorting
var MongoClient = require('mongodb').MongoClient; var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("tutorialpro"); var mysort = { type: 1 }; dbo.collection("site").find().sort(mysort).toArray(function(err, result) { if (err) throw err; console.log(result); db.close(); }); });
### Pagination
To set a specified number of returned documents, you can use the `limit()` method, which accepts one parameter specifying the number of documents to return.
## limit(): Read two documents
var MongoClient = require('mongodb').MongoClient; var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("tutorialpro"); dbo.collection("site").find().limit(2).toArray(function(err, result) { if (err) throw err; console.log(result); db.close(); }); });
To specify the number of documents to skip, you can use the `skip()` method.
## skip(): Skip the first two documents and read two documents
var MongoClient = require('mongodb').MongoClient; var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("tutorialpro"); dbo.collection("site").find().skip(2).limit(2).toArray(function(err, result) { if (err) throw err; console.log(result); db.close(); }); });
### Join Operations
MongoDB is not a relational database, but we can use `$lookup` to perform a left join.
For example, we have two collections with the following data:
Collection 1: orders
[ { _id: 1, product_id: 154, status: 1 } ]
Collection 2: products
[ { _id: 154, name: 'Laptop' }, { _id: 155, name: 'Headphones' }, { _id: 156, name: 'Desktop Computer' } ]
## $lookup to perform a left join
var MongoClient = require('mongodb').MongoClient; var url = "mongodb://127.0.0.1:27017/";
MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("tutorialpro"); dbo.collection('orders').aggregate([ { $lookup: { from: 'products', // Right collection
localField: 'product_id', // Left collection join field
foreignField: '_id', // Right collection join field
as: 'orderdetails' // New field (array type)
}
}
]}).toArray(function(err, res) {
if (err) throw err;
console.log(JSON.stringify(res));
db.close();
});
});
Deleting a Collection
We can use the drop()
method to delete a collection:
drop()
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("tutorialpro");
// Delete the 'test' collection
dbo.collection("test").drop(function(err, delOK) { // delOK returns true if successful, otherwise false
if (err) throw err;
if (delOK) console.log("Collection deleted");
db.close();
});
});
Using Promise
Promise is a class provided by ECMAScript 6 to write complex asynchronous tasks more elegantly.
If you are not familiar with Promise, you can refer to JavaScript Promise.
The following example uses Promise to create a collection:
Example
const MongoClient = require("mongodb").MongoClient;
const url = "mongodb://localhost/tutorialpro";
MongoClient.connect(url).then((conn) => {
console.log("Database connected");
var dbase = conn.db("tutorialpro");
dbase.createCollection("site").then((res) => {
console.log("Collection created");
}).catch((err) => {
console.log("Database operation error");
}).finally(() => {
conn.close();
});
}).catch((err) => {
console.log("Database connection failed");
});
Promise Data Operations
Now we will perform four consecutive operations in a program: add, query, update, delete.
Example
const MongoClient = require("mongodb").MongoClient;
const url = "mongodb://localhost/";
MongoClient.connect(url).then((conn) => {
console.log("Database connected");
const test = conn.db("testdb").collection("test");
// Add
test.insertOne({ "site": "tutorialpro.org" }).then((res) => {
// Query
return test.find().toArray().then((arr) => {
console.log(arr);
});
}).then(() => {
// Update
return test.updateMany({ "site": "tutorialpro.org" },
{ $set: { "site": "example.com" } });
}).then((res) => {
// Query
return test.find().toArray().then((arr) => {
console.log(arr);
});
}).then(() => {
// Delete
return test.deleteMany({ "site": "example.com" });
}).then((res) => {
// Query
return test.find().toArray().then((arr) => {
console.log(arr);
});
}).catch((err) => {
console.log("Data operation failed: " + err.message);
}).finally(() => {
conn.close();
});
}).catch((err) => {
console.log("Database connection failed");
});
Execution result:
Database connected
[ { _id: 5f1664966833e531d83d3ac6, site: 'tutorialpro.org' } ]
[ { _id: 5f1664966833e531d83d3ac6, site: 'example.com' } ]
[]
Implementing the same data operation using async functions
Example
const MongoClient = require("mongodb").MongoClient;
const url = "mongodb://localhost/";
async function dataOperate() {
var conn = null;
try {
conn = await MongoClient.connect(url);
console.log("Database connected");
const test = conn.db("testdb").collection("test");
// Add
await test.insertOne({ "site": "tutorialpro.org" });
// Query
var arr = await test.find().toArray();
console.log(arr);
// Update
await test.updateMany({ "site": "tutorialpro.org" },
{ $set: { "site": "example.com" } });
// Query
arr = await test.find().toArray();
console.log(arr);
// Delete
await test.deleteMany({ "site": "example.com" });
// Query
arr = await test.find().toArray();
console.log(arr);
} catch (err) {
console.log("Error: " + err.message);
} finally {
if (conn != null) conn.close();
}
}
dataOperate();
Running result:
Database connected
[ { _id: 5f169006a2780f0cd4ea640b, site: 'tutorialpro.org' } ]
[ { _id: 5f169006a2780f0cd4ea640b, site: 'example.com' } ]
[]
The running results are exactly the same.
Clearly, async functions are a very good programming style and are very useful when using asynchronous operations multiple times.
However, do not use async functions in node.js versions below 7.6.0. ```