一、介绍
Node.js 是一种运行时环境和服务器端脚本语言,用于构建高度可扩展且响应迅速的应用程序,如博客、电子商务网站和企业门户。与其他NoSQL数据库一样,MongoDB是非表格的。这意味着它存储数据的方式与关系数据库不同,并且具有文档、键值、宽列和图形等数据类型。它具有灵活的架构,可轻松扩展。
您可以使用 Node.js 和 MongoDB 的强大功能来构建现代数据驱动的应用程序。本指南向您展示如何在 Ubuntu 20.04 服务器上使用 Node.js MongoDB 驱动程序实现示例应用程序。
二、准备工作
要遵循本指南:
- 部署 Ubuntu 20.04 服务器。
- 安装MongoDB并配置管理员帐户。
- 安装节点.js(选项 2:通过 PPA 版本安装)。
2.1.设置一个 MongoDB 数据库
在本指南中,示例应用程序将文档(记录)永久存储在 MongoDB 集合中。按照以下步骤初始化数据库并插入一些示例文档:
- 使用管理员帐户凭据登录到MongoDB服务器。替换为正确的用户名。
mongo_db_admin
$ mongosh -u mongo_db_admin -p --authenticationDatabase admin
- 输入您的MongoDB密码,然后按继续。ENTER
输出。
test>
- 运行以下命令以创建示例数据库。
use
my_company
test> use my_company
输出。
switched to db my_company
- 创建一个新集合,并通过运行以下命令将三个示例文档插入到文档中。
employees
my_company> db.employees.insertMany([{ "employee_id" : 1, "first_name" : "JOHN", "last_name" : "DOE" }, { "employee_id" : 2, "first_name" : "MARY", "last_name" : "SMITH" }, { "employee_id" : 3, "first_name" : "DAVID", "last_name" : "JACK" }]);
输出。
{ acknowledged: true, insertedIds: { '0': ObjectId("62f6088b1c072dfeff3a41b8"), '1': ObjectId("62f6088b1c072dfeff3a41b9"), '2': ObjectId("62f6088b1c072dfeff3a41ba") } }
- 查询集合以确保文档已到位。
employees
my_company> db.employees.find()
输出。
[ { _id: ObjectId("62f6088b1c072dfeff3a41b8"), employee_id: 1, first_name: 'JOHN', last_name: 'DOE' }, { _id: ObjectId("62f6088b1c072dfeff3a41b9"), employee_id: 2, first_name: 'MARY', last_name: 'SMITH' }, { _id: ObjectId("62f6088b1c072dfeff3a41ba"), employee_id: 3, first_name: 'DAVID', last_name: 'JACK' } ]
- 从 MongoDB 服务器注销。
my_company> quit
设置数据库并插入示例记录后,继续下一步并创建一个数据库类,该类允许您在 Node.js 代码中与 MongoDB 数据库进行交互。
三. 创建类mongo_db_gateway
每个 Node.js 应用程序都需要一个单独的目录,以避免混合源代码和系统文件。您应该将所有应用程序文件放在该目录中。对于此应用程序,您应该首先对文件进行编码。此类文件承载用于管理数据库连接和执行其他操作(如插入、查找、更新和删除文档)的方法。mongo_db_gateway.js
- 首先创建一个新目录。
project
$ mkdir project
- 导航到新目录。
project
$ cd project
- 在文本编辑器中打开一个新文件。
mongo_db_gateway.js
$ nano mongo_db_gateway.js
- 在文件中输入以下信息。将值 () 替换为正确的 MongoDB 密码。
mongo_db_gateway.js
dbPass
EXAMPLE_PASSWORD
class mongo_db_gateway { connect(callBack) { const MongoClient = require('mongodb').MongoClient; const dbHost = 'localhost'; const dbUser = 'mongo_db_admin'; const dbPass = 'EXAMPLE_PASSWORD'; const dbPort = 27017; const dbName = "my_company"; const conString = "mongodb://" + dbUser + ":" + dbPass + "@" + dbHost + ":" + dbPort; MongoClient.connect(conString, function(err, dbClient) { if (!err) { const mongoDb = dbClient.db(dbName); callBack(null, mongoDb); } }); } insertDocument(data, callBack) { this.connect(function (dbErr, mongoDb) { if (!dbErr) { mongoDb.collection("employees").insertOne(data, function(err, result) { if (err) { callBack(err, null); } else { callBack(null, result); } }); } }); } findDocuments(resourceId, callBack) { this.connect(function (dbErr, mongoDb) { if (!dbErr) { var query = {}; if (resourceId != "") { query = {"employee_id": parseInt(resourceId)}; } mongoDb.collection("employees").find(query).toArray(function(err, result) { if (err) { callBack(err, null); } else { callBack(null, result); } }); } }); } updateDocument(resourceId, data, callBack) { this.connect(function (dbErr, mongoDb) { if (!dbErr) { var query = {"employee_id": parseInt(resourceId)}; data = {$set: data}; mongoDb.collection("employees").updateOne(query, data, function(err, result) { if (err) { callBack(err, null); } else { callBack(null, result); } }); } }); } deleteDocument(resourceId, callBack) { this.connect(function (dbErr, mongoDb) { if (!dbErr) { var query = {"employee_id": parseInt(resourceId)}; mongoDb.collection("employees").deleteOne(query, function(err, result) { if (err) { callBack(err, null); } else { callBack(null, result); } }); } }); } } module.exports = mongo_db_gateway;
- 保存并关闭文件。
mongo_db_gateway.js
mongo_db_gateway.js
文件解释道:
- 类文件包含如下所示的五个方法。
mongo_db_gateway.js
class mongo_db_gateway { connect(callBack) { ... } insertDocument(data, callBack) { ... } findDocuments(resourceId, callBack) { ... } updateDocument(resourceId, data, callBack) { ... } deleteDocument(resourceId, callBack) { ... } }
- 五种不同方法的功能如下:
connect()
:此方法使用数据库凭据通过函数连接到 MongoDB 数据库。MongoClient.connect()
insertDocument(data, callBack)
:此方法接受两个参数。该参数是来自 HTTP 客户端的 JSON 有效负载,请求将文档插入集合中。参数是在函数完成时运行的特殊函数。该语句是将数据插入MongoDB数据库的实际函数。data
employees
callBack
insertDocument(...)
mongoDb.collection("employees").insertOne(..)
findDocuments(resourceId, callBack)
:此函数类似于 SQL 语句。该函数接受两个值。这是您要从集合中返回的员工。参数是在代码执行时运行的函数。在函数下,你正在检查 的值,以制作适合该函数的值,如下图所示。空筛选器 () 查询返回集合中的所有文档。否则,筛选器查询将返回特定文档。SELECT * FROM SAMPLE_TABLE WHERE CONDITION = SOME_VALUE
findDocuments()
resourceId
employee_id
callBack
findDocuments(...)
resourceId
query
mongoDb.collection("employees").find(query).toArray(...)
{}
{"employee_id": parseInt(resourceId)}
... var query = {}; if (resourceId != "") { query = {"employee_id": parseInt(resourceId)}; } mongoDb.collection("employees").find(query).toArray(...) ...
updateDocument(resourceId, data, callBack)
:该函数接受三个参数。该参数为要更新的文档定义筛选器。是具有新文档值的 JSON 有效负载。参数是函数在完成后调用的函数。该函数运行该函数以更新与筛选器查询匹配的文档。updateDocument(...)
resourceId
data
callBack
updateDocument(...)
updateDocument(...)
mongoDb.collection("employees").updateOne(query, data, ...
deleteDocument(resourceId, callBack)
:该函数接受两个参数。该参数允许您根据下图创建筛选器查询以删除文档。deleteDocument(...)
resourceId
... var query = {"employee_id": parseInt(resourceId)}; mongoDb.collection("employees").deleteOne(query...) ...
- 文件末尾的行允许您使用该语句将模块导入其他 Node.js 文件中。
module.exports = mongo_db_gateway;
mongo_db_gateway.js
require('./mongo_db_gateway.js')
您的模块现已准备就绪。下一步演示如何调用类方法来插入、查找、更新和删除文档。mongo_db_gateway.js
mongo_db_gateway
四. 创建文件index.js
每个 Node.js 应用程序都需要一个在应用程序启动时执行的入口点。本指南使用文件作为入口点。请按照以下步骤创建文件:index.js
- 在文本编辑器中打开一个新文件。
index.js
$ nano index.js
- 在文件中输入以下信息。
index.js
const http = require('http'); const url = require("url"); const mongo_db_gateway = require('./mongo_db_gateway'); const httpHost = '127.0.0.1'; const httpPort = 8080; const httpServer = http.createServer(httpHandler); httpServer.listen(httpPort, httpHost, () => { console.log(`HTTP server running at http://${httpHost}:${httpPort}/`); }); function httpHandler(req, res) { var pathname = url.parse(req.url).pathname; var resourcePath = pathname.split("/"); resourceId = ""; if (resourcePath.length >= 3) { resourceId = resourcePath[2] } const dg = new mongo_db_gateway(); switch (req.method) { case "POST": var jsonData = ""; req.on('data', function (data) { jsonData += data; }); req.on('end', function () { dg.insertDocument(JSON.parse(jsonData), callBack); }); break; case "PUT": var jsonData = ""; req.on('data', function (data) { jsonData += data; }); req.on('end', function () { dg.updateDocument(resourceId, JSON.parse(jsonData), callBack); }); break; case "DELETE": dg.deleteDocument(resourceId, callBack); break; case "GET": dg.findDocuments(resourceId, callBack); break; } function callBack(err, result) { res.writeHead(200, {'Content-Type': 'application/json'}); if (!err) { res.write(JSON.stringify(result, null, 4)); } else { res.write(err); } res.end(); } }
- 保存并关闭文件。
index.js
索引.js
文件解释:
- 文件中的前三行将运行此示例应用程序所需的模块与您之前编码的自定义模块一起导入。该模块为您的应用程序提供 HTTP 功能,并允许您使用和运行 Node.js内置 Web 服务器。该模块将 Web 地址拆分为不同的部分并返回资源路径。
index.js
mongo_db_gateway.js
http
url
const http = require('http'); const url = require("url"); const mongo_db_gateway = require('./mongo_db_gateway'); ...
- 以下两行定义 HTTP 服务器的地址和端口。
... const httpHost = '127.0.0.1'; const httpPort = 8080; ...
- 以下行定义一个新的 HTTP 服务器并指定一个回调函数 ()。
httpHandler
... const httpServer = http.createServer(httpHandler); ...
- 下面的行指示 Web 服务器侦听传入的 HTTP 请求,并在代码运行时在控制台上打印消息。
... httpServer.listen(httpPort, httpHost, () => { console.log(`HTTP server running at http://${httpHost}:${httpPort}/`); }); ...
- 以下行定义一个函数。
httpHandler(req, res) {...}
... httpHandler(req, res) { ... } ...
- 以下行从请求 URL 中检索 。例如,当 HTTP 客户端请求 URL 时,下面的逻辑将检索为 .您正在使用该值通过制作MongoDB理解的搜索过滤器来查找,更新和删除文档。
resourceId
http://127.0.0.1:8080/employees/4
4
resourceId
resourceId
... var pathname = url.parse(req.url).pathname; var resourcePath = pathname.split("/"); resourceId = ""; if (resourcePath.length >= 3) { resourceId = resourcePath[2] } ...
- 文件中的下一行初始化您之前创建的模块。然后,使用 Node.js 语句将 HTTP(、、 和 )映射到相应的数据库函数(、、 和 )。
index.js
mongo_db_gateway
switch(...){...}
req.methods
POST
GET
PUT
DELETE
dg.insertDocument(...)
dg.getDocuments(...)
dg.updateDocument(...)
dg.deleteDocument(...)
... const dg = new mongo_db_gateway(); switch (req.method) { ... } ...
- 文件末尾的函数在MongoDB完成数据库操作时运行。然后,使用该语句编写对调用 HTTP 客户端的响应。
callBack()
index.js
res.write(JSON.stringify(result, null, 4));
... function callBack(err, result) { res.writeHead(200, {'Content-Type': 'application/json'}); if (!err) { res.write(JSON.stringify(result, null, 4)); } else { res.write(err); } res.end(); } ...
现在,您拥有运行应用程序所需的所有源代码文件。下一步侧重于测试应用程序。
五. 测试应用程序
创建 MongoDB 数据库并对所有源代码文件进行编码后,您的应用程序现在可以进行测试了。按照以下步骤测试应用程序:
- 确保您拥有最新版本。
npm
$ sudo npm install npm -g
输出。
changed 41 packages, and audited 206 packages in 4s ... found 0 vulnerabilities
- 用于初始化目录。
npm
project
$ npm init
- 出现提示时,输入以下响应。
package name: (project) project ENTER version: (1.0.0) 1.0.0 ENTER description: Node.js and MongoDB ENTER entry point: (index.js) index.js ENTER test command: ENTER git repository: ENTER keywords: Node.js, MongoDB ENTER author: Test author ENTER license: (ISC) ENTER About to write to ...package.json: ... Is this OK? (yes) yes
- 安装 MongoDB Node.js 驱动程序模块 ()。
mongodb
$ npm install mongodb
- 运行应用程序。请记住,index.js 是应用程序的入口点。
$ node index.js
应用程序启动 Web 服务器并显示以下输出。不要在活动终端窗口中输入任何其他命令。
HTTP server running at http://127.0.0.1:8080/
- 建立与服务器的另一个连接,并使用 Linux 命令运行以下测试命令。
SSH
curl
- 创建新文档:
$ curl -X POST http://127.0.0.1:8080/employees -H 'Content-Type: application/json' -d '{"employee_id": 4, "first_name": "HENRY", "last_name": "JACKSON"}'
输出。
{ "acknowledged": true, "insertedId": "62f77136ebf1445162cbd181" }
- 检索所有文档:
$ curl -X GET http://localhost:8080/employees
输出。
[ { "_id": "62f770c2740ed2290a62d7ad", "employee_id": 1, "first_name": "JOHN", "last_name": "DOE" }, { "_id": "62f770c2740ed2290a62d7ae", "employee_id": 2, "first_name": "MARY", "last_name": "SMITH" }, { "_id": "62f770c2740ed2290a62d7af", "employee_id": 3, "first_name": "DAVID", "last_name": "JACK" }, { "_id": "62f77136ebf1445162cbd181", "employee_id": 4, "first_name": "HENRY", "last_name": "JACKSON" } ]
- 检索特定文档:
$ curl -X GET http://localhost:8080/employees/4
输出。
[ { "_id": "62f77136ebf1445162cbd181", "employee_id": 4, "first_name": "HENRY", "last_name": "JACKSON" } ]
- 更新文档 (
resouceId 4
):$ curl -X PUT http://127.0.0.1:8080/employees/4 -H 'Content-Type: application/json' -d '{"employee_id": 4, "first_name": " JACK", "last_name": "GEOFREY"}'
输出。
{ "acknowledged": true, "modifiedCount": 1, "upsertedId": null, "upsertedCount": 0, "matchedCount": 1 }
- 确认更新命令:
$ curl -X GET http://localhost:8080/employees/4
输出。
[ { "_id": "62f770c2740ed2290a62d7ad", "employee_id": 4, "first_name": " JACK", "last_name": "GEOFREY" } ]
- 删除文档:
$ curl -X DELETE http://localhost:8080/employees/2
输出。
{ "acknowledged": true, "deletedCount": 1 }
- 确认删除命令:
$ curl -X GET http://localhost:8080/employees/2
输出。
[]
- 创建新文档:
六、结论
本指南使用 Node.js 和 Ubuntu 20.04 服务器实现 MongoDB 文档数据库。您已经设置了数据库,创建了中央数据库模块,并定义了应用程序的入口点。然后,您使用 Linux 命令运行不同的测试来插入、查找、更新和删除文档。使用本指南中的知识在使用 Node.js 和 MongoDB 时构建下一个数据驱动应用程序。curl