【51CTO.com快译】MongoDB是最早的NoSQL数据存储之一,也是目前流行的NoSQL数据存储。Node.js的JavaScript运行时继续在后端开发中占据主导地位。它们共同构成了一个高度灵活和动态的技术堆栈。
Node.js和MongoDB允许快速实现基本的应用程序功能,如CRUD(创建、读取、更新和删除)操作。在本文中,我们将使用最新的 Node.js MongoDB 驱动程序(版本 3.6+)来了解 CRUD 基础知识。
Node.js 和 MongoDB 设置
先在系统上安装Node.js和MongoDB,以及一个包含`curl`可用命令的命令行。(如果你使用的是 2018 年以后的 Linux、MacOS 或 Windows 10 版本,则很可能使用[curl](https://curl.se/)。)
下载系统适用的MongoDB后,可以将其安装为服务或将其作为可执行文件运行。无论哪种方式,请通过打开命令行并运行`mongo`命令来确保 MongoDB 正在运行。(如果没有作为服务安装,可能需要将该命令添加到路径中。)这使你可以访问系统上运行的 MongoDB 实例。
接下来,确保安装了 Node.js 和 npm。在命令行中,键入`node -v`。如果安装了 Node.js,将获得版本号。如果没有,则需要下载Node.js并安装到机器上。
Curl允许从命令行执行简单的HTTP请求。例如,运行`curl www.google.com`将收到来自 Google 主页的标记。
创建一个 Node.js 项目
在文件夹中创建一个npm init类型的新项目。项目名称可以使用node-mongo-intro。当然,你也可以接受其他缺省值。
添加所需的依赖项。在刚创建的项目目录中,键入`npm install mongodb polka --save`. 这将安装 MongoDB 的 Node.js 驱动程序(允许项目访问 MongoDB)和用于处理 HTTP 请求的Polka HTTP 服务器。
编辑 package.json 文件以包含启动脚本,如Listing 1 所示。
Listing 1. A start script
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node src/index" // <-- add this line
},
接着创建一个 /node-mongo-intro/src/index.js 文件,并将Listing 2 的内容放入其中。
Listing 2. HTTP test in index.js
const polka = require('polka');
polka()
.get('/create', (req, res) => {
res.end(`works`);
})
.listen(3000, err => {
if (err) throw err;
console.log(`> Running on localhost:3000`);
});
现在用`npm run start`启动服务器。服务器将在端口3000上侦听。你可以使用curl http://localhost:3000/create进行测试。测试后应该会看到“works”的响应(以及一些curl请求信息)。
在 MongoDB 中插入一条记录
现在我们将执行一个简单的插入。这是 CRUD 中的 “C”。将`index.js`文件更新为如Listing 3 所示。
Listing 3. A simple insert
const polka = require('polka');
const { MongoClient } = require("mongodb");
polka()
.get('/create', (req, res) => {
const client = new MongoClient("mongodb://localhost:27017");
async function run() {
try {
await client.connect();
const database = client.db("intro");
const collection = database.collection("quotes");
const result = await collection.insertOne({"quote":"Life is what happens to you while you're busy making other plans."});
res.end(JSON.stringify(result));
} catch (e) {
console.log("Error: " + e);
} finally {
await client.close();
}
}
run().catch(console.dir);
})
.listen(3000, err => {
if (err) throw err;
console.log(`> Running on localhost:3000`);
});
Listing 3 中的代码打开到本地系统上 MongoDB 实例的连接,然后指定一个数据库 ( `"intro"`) 和集合 ( `"quotes"`)。集合类似于关系数据库中的表。
接下来,代码插入一个文档(类似于 SQL 记录)并在一个HTTP响应中发送结果。
运行插入
首先,按 Ctrl-C 停止并重新启动节点服务器。然后在命令行运行这个命令:
npm run startcurl http : //localhost:3000/create
验证插入
如果你掌握 SQL 技术,你会注意到的一件事是,我们在进行这项工作之前没有创建表和模式。我们甚至没有创建我们使用的数据库。因为 MongoDB 为我们完成了这些所需的工作,它可以接受任何类型的结构化键值文档到集合中。
使用mongo打开mongo shell,并输入命令use intro。这将切换到自动创建的intro数据库。现在输入db.quotes.find()命令,将看到该记录被插入。注意MongoDB会在“_id”字段上自动生成一个唯一的ID。你可以通过在文档上自己指定一个来覆盖它。
在MongoDB中检索文档
现在让我们把文件拿出来。添加如 Listing 4所示的.get()映射。这是CRUD中的“R”。
Listing 4. Retrieve a document
.get('/retrieve', (req, res) => {
const client = new MongoClient("mongodb://localhost:27017");
async function run() {
try {
await client.connect();
const database = client.db("intro");
const collection = database.collection("quotes");
const cursor = collection.find({}, {});
let items = [];
await cursor.forEach(function(doc){
items.push(doc);
});
res.end(JSON.stringify(items));
} catch (error){
console.warn("ERROR: " + error);
if (errCallback) errCallback(error);
} finally {
await client.close();
}
}
run().catch(console.dir);
})
Listing 4 以与Listing 3 相同的方式连接,然后发出一个`find`命令,并带有一个空查询。这意味着它匹配所有文档。接下来,它接收响应并将其编组到一个数组中以发送回客户端。
注意,游标操作和集合是异步的。清单3中的collection.insertOne也是如此。我们使用await关键字来处理这些,而不使用嵌套的回调。
使用curl http://localhost:3000/retrieve测试新端点(在停止并再次启动服务器之后),将看到返回的集合。
MongoDB中更新文档
现在是CRUD中的“U”。Listing 5处理了这一点。
Listing 5. Updating a document
.get('/update', (req, res) => {
const client = new MongoClient("mongodb://localhost:27017");
async function run() {
try {
await client.connect();
const database = client.db("intro");
const collection = database.collection("quotes");
const updateDoc = {
$set: {
author:
"John Lennon",
},
};
const result = await collection.updateOne({}, updateDoc, {}); // <-- empty filter matches all docs
res.end("Updated: " + result.modifiedCount);
} catch (e) {
errCallback(e);
} finally {
await client.close();
}
}
run().catch(console.dir);
})
Listing 5 再次连接到数据库,然后创建一个更新文档。本文档通过指定一个`$set`包含要更改的字段和值的对象的字段来告诉 MongoDB 要更改什么。在我们的例子中,我们将该`author`字段设置为`"John Lennon"`,即相关引用的引用者。
接下来,Listing 5 使用该`updateOne()`函数来执行更新文档。最后一个空对象参数是过滤器。在这种情况下,我们希望匹配所有文档,因此我们将其留空。
最后,我们发回我们更新的文档数量(一个)。
MongoDB中删除文档
CRUD的最后一个字母是“D”,表示删除。
删除操作的映射如Listing 6所示。
Listing 6. Deleting a document
.get('/delete', (req, res) => {
const client = new MongoClient("mongodb://localhost:27017");
async function run() {
try {
await client.connect();
const database = client.db("intro");
const collection = database.collection("quotes");
const query = { };
const result = await collection.deleteOne(query);
if (result.deletedCount === 1) {
res.end("Successfully deleted one document.");
} else {
res.end("Deleted 0 documents.");
}
} finally {
await client.close();
}
}
这里我们再次使用空查询来匹配`"quotes"`集合中的所有文档。async`collection.deleteOne()`函数返回一个结果,告诉我们有多少文档受到影响。
重新启动服务器 (Ctrl-C) 并发出新的 curl 命令:
curl http://localhost:3000/delete
您可以使用curl http://localhost:3000/retrieve来验证文档是否已被删除。
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】