多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# MongoDB JavaScript 教程 > 原文: [http://zetcode.com/javascript/mongodb/](http://zetcode.com/javascript/mongodb/) MongoDB JavaScript 教程展示了如何在 JavaScript 中创建与 MongoDB 一起使用的程序。 本教程使用本地 mongodb 驱动程序。 (还有其他解决方案,例如 Mongoose 或 Monk。) ## MongoDB MongoDB 是 NoSQL 跨平台的面向文档的数据库。 它是可用的最受欢迎的数据库之一。 MongoDB 由 MongoDB Inc. 开发,并作为免费和开源软件发布。 MongoDB 中的记录是一个文档,它是由字段和值对组成的数据结构。 MongoDB 文档与 JSON 对象相似。 字段的值可以包括其他文档,数组和文档数组。 MongoDB 将文档存储在集合中。 集合类似于关系数据库中的表以及行中的文档。 ## 安装 MongoDB 服务器 以下命令可用于在基于 Debian 的 Linux 上安装 MongoDB。 ```js $ sudo apt-get install mongodb ``` 该命令将安装 MongoDB 随附的必要包。 ```js $ sudo service mongodb status mongodb start/running, process 975 ``` 使用`sudo service mongodb status`命令,我们检查`mongodb`服务器的状态。 ```js $ sudo service mongodb start mongodb start/running, process 6448 ``` `mongodb`服务器由`sudo service mongodb start`命令启动。 ## MongoDB 驱动程序安装 我们设置了项目。 ```js $ node -v v11.5.0 ``` 我们使用 Node.js 版本 11.5.0。 ```js $ npm i mongodb ``` 我们安装`mongodb`本机 JavaScript 驱动程序。 `npm`是 Node.js 包管理器。 MongoDB Node.js 驱动程序提供基于回调和基于`Promise`的交互。 ## MongoDB 创建数据库 `mongo`工具是 MongoDB 的交互式 JavaScript Shell 界面,它为系统管理员提供了一个界面,并为开发者提供了一种直接测试数据库查询和操作的方法。 ```js $ mongo testdb MongoDB shell version v4.0.7 ... > db testdb > db.cars.insert({name: "Audi", price: 52642}) > db.cars.insert({name: "Mercedes", price: 57127}) > db.cars.insert({name: "Skoda", price: 9000}) > db.cars.insert({name: "Volvo", price: 29000}) > db.cars.insert({name: "Bentley", price: 350000}) > db.cars.insert({name: "Citroen", price: 21000}) > db.cars.insert({name: "Hummer", price: 41400}) > db.cars.insert({name: "Volkswagen", price: 21600}) ``` 我们创建一个`testdb`数据库,并在`cars`集合中插入八个文档。 ## MongoDB `Promise` `Promise`是用于延迟和异步计算的对象。 它表示尚未完成的操作,但有望在将来进行。 ```js asyncFunc() .then(value => { /* success */ }) .catch(error => { /* failure */ }) .finally( => { /* cleanup */}; ``` `then()`方法始终返回`Promise`,这使我们能够链接方法调用。 > **注意**:如果没有传递回调,`MongoClient`的`connect`将返回一个`Promise`。 我们也可以使用`async/await`语法来处理`Promise`。 ## MongoDB JS 驱动程序 在第一个示例中,我们打印 Node.js 驱动程序的版本。 `driver_version.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; console.log(client.topology.clientInfo); client.close(); }); ``` 在该示例中,我们连接到服务器并找到客户端信息。 ```js const mongo = require('mongodb'); ``` 我们使用`mongodb`模块。 ```js const client = mongo.MongoClient; ``` `MongoClient`用于连接到 MongoDB 服务器。 ```js const url = 'mongodb://localhost:27017'; ``` 这是数据库的 URL。 27017 是 MongoDB 服务器监听的默认端口。 ```js MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { ``` 使用`connect()`创建到数据库的连接。 ```js $ node driver_version.js { driver: { name: 'nodejs', version: '3.2.2' }, os: { type: 'Windows_NT', name: 'win32', architecture: 'x64', version: '10.0.17134' }, platform: 'Node.js v11.5.0, LE' } ``` 驱动程序版本为 3.2.2。 ## MongoDB 列出数据库集合 `listCollections()`方法列出了数据库中的可用集合。 `list_collections.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); db.listCollections().toArray().then((docs) => { console.log('Available collections:'); docs.forEach((doc, idx, array) => { console.log(doc.name) }); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例连接到`testdb`数据库并检索其所有集合。 ```js db.listCollections().toArray().then((docs) => { console.log('Available collections:'); docs.forEach((doc, idx, array) => { console.log(doc.name) }); ... ``` `listCollection()`方法在`testdb`数据库中找到所有集合; 它们被打印到控制台。 > **注意**:我们应该谨慎使用`toArray()`方法,因为它会导致大量的内存使用。 ```js }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); ``` 在`catch`块中,我们捕获了任何潜在的异常,并在`finally`块中关闭了与数据库的连接。 > **注意**:我们的应用是控制台程序; 因此,我们在程序结束时关闭连接。 在 Web 应用中,应重新使用连接。 ```js $ node list_collections.js Available collections: continents cars cities ``` 在我们的数据库中,我们有这三个集合。 ## MongoDB 数据库统计 `dbstats()`方法获取数据库的统计信息。 `dbstats.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); db.stats((err, stats) => { if (err) throw err; console.log(stats); client.close(); }) }); ``` 该示例连接到`testdb`数据库并显示其统计信息。 ```js $ node dbstats.js { db: 'testdb', collections: 3, views: 0, objects: 18, avgObjSize: 57.888888888888886, dataSize: 1042, storageSize: 69632, numExtents: 0, indexes: 3, indexSize: 69632, fsUsedSize: 136856346624, fsTotalSize: 254721126400, ok: 1 } ``` 这是一个示例输出。 ## MongoDB 查找 `find()`函数为查询创建一个游标,该游标可用于遍历 MongoDB 的结果。 `find_all.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); db.collection('cars').find({}).toArray().then((docs) => { console.log(docs); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 在示例中,我们从`cars`集合中检索所有文档。 ```js db.collection('cars').find({}).toArray().then((docs) => { ``` 传递空查询将返回所有文档。 ```js $ node find_all.js [ { _id: 5cfcfc3438f62aaa09b52175, name: 'Audi', price: 52642 }, { _id: 5cfcfc3a38f62aaa09b52176, name: 'Mercedes', price: 57127 }, { _id: 5cfcfc3f38f62aaa09b52177, name: 'Skoda', price: 9000 }, { _id: 5cfcfc4338f62aaa09b52178, name: 'Volvo', price: 29000 }, { _id: 5cfcfc4838f62aaa09b52179, name: 'Bentley', price: 350000 }, { _id: 5cfcfc4b38f62aaa09b5217a, name: 'Citroen', price: 21000 }, { _id: 5cfcfc4f38f62aaa09b5217b, name: 'Hummer', price: 41400 }, { _id: 5cfcfc5438f62aaa09b5217c, name: 'Volkswagen', price: 21600 } ] ``` 这是输出。 ## MongoDB 计数文件 `count()`函数返回集合中匹配文档的数量。 `count_documents.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); db.collection('cars').find({}).count().then((n) => { console.log(`There are ${n} documents`); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例计算`cars`集合中的文档数。 ```js $ node count_documents.js There are 8 documents ``` 现在,汽车集合中有八个文件。 ## MongoDB `findOne` `findOne()`方法返回一个满足指定查询条件的文档。 如果多个文档满足查询条件,则此方法将根据反映磁盘上文档顺序的自然顺序返回第一个文档。 `find_one.js` ```js const MongoClient = require('mongodb').MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); let collection = db.collection('cars'); let query = { name: 'Volkswagen' } collection.findOne(query).then(doc => { console.log(doc); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例从`cars`集合中读取一个文档。 ```js let query = { name: 'Volkswagen' } ``` 该查询包含汽车的名称-大众汽车。 ```js collection.findOne(query).then(doc => { ``` 该查询将传递给`findOne()`方法。 ```js $ node find_one.js { _id: 8, name: 'Volkswagen', price: 21600 } ``` 这是示例的输出。 ## MongoDB 异步/等待示例 使用`async/await`,我们可以轻松地以同步方式处理`Promise`。 `async_await.js` ```js const MongoClient = require('mongodb').MongoClient; const url = 'mongodb://localhost:27017'; async function findCar() { const client = await MongoClient.connect(url, { useNewUrlParser: true }) .catch(err => { console.log(err); }); if (!client) { return; } try { const db = client.db("testdb"); let collection = db.collection('cars'); let query = { name: 'Volkswagen' } let res = await collection.findOne(query); console.log(res); } catch (err) { console.log(err); } finally { client.close(); } } findCar(); ``` 该示例使用`async/await`读取一个文档。 ```js async function findCar() { ``` 该函数具有`async`关键字。 ```js let res = await collection.findOne(query); ``` 使用`await`,我们等待`findOne()`函数的结果。 ## MongoDB 查询运算符 可以使用 MongoDB 查询运算符(例如`$gt`,`$lt`或`$ne`)过滤数据。 `read_gt.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); let query = { price: { $gt: 30000 } }; db.collection('cars').find(query).toArray().then((docs) => { console.log(docs); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例打印汽车价格大于 30,000 的所有文档。 ```js let query = { price: { $gts: 30000 } }; ``` `$gt`运算符用于获取价格大于 30,000 的汽车。 ```js $ node read_gt.js [ { _id: 5d03e40536943362cffc84a7, name: 'Audi', price: 52642 }, { _id: 5d03e40a36943362cffc84a8, name: 'Mercedes', price: 57127 }, { _id: 5d03e41936943362cffc84ab, name: 'Bentley', price: 350000 }, { _id: 5d03e42236943362cffc84ad, name: 'Hummer', price: 41400 } ] ``` 这是示例的输出。 仅包括价格超过 30,000 的汽车。 `$and`逻辑运算符可用于组合多个表达式。 `read_gt_lt.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); let query = { $and: [{ price: { $gt: 20000 } }, { price: { $lt: 50000 } }] }; db.collection('cars').find(query).toArray().then((docs) => { console.log(docs); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 在示例中,我们检索价格在 20,000 到 50,000 之间的汽车。 ```js let query = { $and: [{ price: { $gt: 20000 } }, { price: { $lt: 50000 } }] }; ``` `$and`运算符将`$gt`和`$lt`组合在一起以获得结果。 ```js $ node read_gt_lt.js [ { _id: 5d03e41336943362cffc84aa, name: 'Volvo', price: 29000 }, { _id: 5d03e41e36943362cffc84ac, name: 'Citroen', price: 21000 }, { _id: 5d03e42236943362cffc84ad, name: 'Hummer', price: 41400 }, { _id: 5d03e42636943362cffc84ae, name: 'Volkswagen', price: 21600 } ] ``` 这是示例的输出。 ## MongoDB 预测 投影确定从数据库传递哪些字段。 `projections.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); db.collection('cars').find({}).project({_id: 0}).toArray().then((docs) => { console.log(docs); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例从输出中排除`_id`字段。 ```js db.collection('cars').find({}).project({_id: 0}).toArray().then((docs) => { ``` `project()`方法设置查询的投影; 它不包括`_id`字段。 ```js $ node projections.js [ { name: 'Audi', price: 52642 }, { name: 'Mercedes', price: 57127 }, { name: 'Skoda', price: 9000 }, { name: 'Volvo', price: 29000 }, { name: 'Bentley', price: 350000 }, { name: 'Citroen', price: 21000 }, { name: 'Hummer', price: 41400 }, { name: 'Volkswagen', price: 21600 } ] ``` 这是示例的输出。 ## MongoDB 限制数据输出 `limit()`方法指定要返回的文档数,`skip()`方法指定要跳过的文档数。 `skip_limit.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); db.collection('cars').find({}).skip(2).limit(5).toArray().then((docs) => { console.log(docs); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例从`cars`集合中读取,跳过前两个文档,并将输出限制为五个文档。 ```js db.collection('cars').find({}).skip(2).limit(5).toArray().then((docs) => { ``` `skip()`方法跳过前两个文档,`limit()`方法将输出限制为五个文档。 ```js $ node skip_limit.js [ { _id: 5d03e40f36943362cffc84a9, name: 'Skoda', price: 9000 }, { _id: 5d03e41336943362cffc84aa, name: 'Volvo', price: 29000 }, { _id: 5d03e41936943362cffc84ab, name: 'Bentley', price: 350000 }, { _id: 5d03e41e36943362cffc84ac, name: 'Citroen', price: 21000 }, { _id: 5d03e42236943362cffc84ad, name: 'Hummer', price: 41400 } ] ``` 这是示例的输出。 ## MongoDB 聚合 聚合计算集合中数据的聚合值。 `sum_all_cars.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); let myagr = [{$group: {_id: 1, all: { $sum: "$price" } }}]; db.collection('cars').aggregate(myagr).toArray().then((sum) => { console.log(sum); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例计算集合中所有汽车的价格。 ```js let myagr = [{$group: {_id: 1, all: { $sum: "$price" } }}]; ``` `$sum`运算符计算并返回数值的总和。 `$group`运算符通过指定的标识符表达式对输入文档进行分组,并将累加器表达式(如果指定)应用于每个组。 ```js db.collection('cars').aggregate(myagr).toArray().then((sum) => { ``` `aggregate()`函数将聚合操作应用于`cars`集合。 ```js $ node sum_all_cars.js [ { _id: 1, all: 581769 } ] ``` 所有价格的总和是 581,769。 我们可以使用`$match`运算符来选择要汇总的特定汽车。 `sum_two_cars.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); let myagr = [ { $match: { $or: [{ name: "Audi" }, { name: "Volvo" }] } }, { $group: { _id: 1, sum2cars: { $sum: "$price" } } } ]; db.collection('cars').aggregate(myagr).toArray().then((sum) => { console.log(sum); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例计算奥迪和沃尔沃汽车的价格总和。 ```js let myagr = [ { $match: { $or: [{ name: "Audi" }, { name: "Volvo" }] } }, { $group: { _id: 1, sum2cars: { $sum: "$price" } } } ]; ``` 该表达式使用`$match`,`$or`,`$group`和`$sum`运算符执行任务。 ```js $ node sum_two_cars.js [ { _id: 1, sum2cars: 81642 } ] ``` 两辆车的价格之和为 81,642。 ## MongoDB `insertOne` `insertOne()`方法将单个文档插入到集合中。 `insert_one.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const ObjectID = mongo.ObjectID; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); let doc = {_id: new ObjectID(), name: "Toyota", price: 37600 }; db.collection('cars').insertOne(doc).then((doc) => { console.log('Car inserted') console.log(doc); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例将一辆汽车插入`cars`集合。 ```js let doc = {_id: new ObjectID(), name: "Toyota", price: 37600 }; ``` 这是要插入的文档。 使用`ObjectID`生成一个新的 ID。 ```js db.collection('cars').insertOne(doc).then((doc) => { ``` `insertOne()`函数将文档插入到集合中。 ```js > db.cars.find({name:'Toyota'}) { "_id" : ObjectId("5d03d4321f9c262a50e671ee"), "name" : "Toyota", "price" : 37600 } ``` 我们用`mongo`工具确认插入。 ## MongoDB `insertMany()` `insertMany()`函数可将多个文档插入一个集合中。 `insert_many.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const ObjectID = mongo.ObjectID; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); let collection = db.collection('continents'); let continents = [ { _id: new ObjectID(), name: "Africa" }, { _id: new ObjectID(), name: "America" }, { _id: new ObjectID(), name: "Europe" }, { _id: new ObjectID(), name: "Asia" }, { _id: new ObjectID(), name: "Australia" }, { _id: new ObjectID(), name: "Antarctica" } ]; collection.insertMany(continents).then(result => { console.log("documents inserted into the collection"); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例创建一个`continents`集合并将六个文档插入其中。 ```js let collection = db.collection('continents'); ``` `collection()`方法检索集合; 如果集合不存在,则会创建它。 ```js let continents = [ { _id: new ObjectID(), name: "Africa" }, { _id: new ObjectID(), name: "America" }, { _id: new ObjectID(), name: "Europe" }, { _id: new ObjectID(), name: "Asia" }, { _id: new ObjectID(), name: "Australia" }, { _id: new ObjectID(), name: "Antarctica" } ]; ``` 这是要插入新集合的六个记录的数组。 `ObjectID()`创建一个新的 ObjectID,这是用于标识文档的唯一值,而不是整数。 ```js collection.insertMany(continents).then(result => { console.log("documents inserted into the collection"); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); ``` `insertMany()`方法将文档数组插入`continents`集合。 ```js > db.continents.find() { "_id" : ObjectId("5cfcf97732fc4913748c9669"), "name" : "Africa" } { "_id" : ObjectId("5cfcf97732fc4913748c966a"), "name" : "America" } { "_id" : ObjectId("5cfcf97732fc4913748c966b"), "name" : "Europe" } { "_id" : ObjectId("5cfcf97732fc4913748c966c"), "name" : "Asia" } { "_id" : ObjectId("5cfcf97732fc4913748c966d"), "name" : "Australia" } { "_id" : ObjectId("5cfcf97732fc4913748c966e"), "name" : "Antarctica" } ``` `continents`集合已成功创建。 ## MongoDB deleteOne `deleteOne()`方法用于删除文档。 `delete_one.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); let query = { name: "Volkswagen" }; db.collection('cars').deleteOne(query).then((result) => { console.log('Car deleted'); console.log(result); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例删除文档。 ```js let query = { name: "Volkswagen" }; db.collection('cars').deleteOne(query).then((result) => { ... ``` `deleteOne()`删除`Volkswagen`的文档。 ## MongoDB `updateOne()` `updateOne()`函数用于更新文档。 `update_one.js` ```js const mongo = require('mongodb'); const MongoClient = mongo.MongoClient; const url = 'mongodb://localhost:27017'; MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => { if (err) throw err; const db = client.db("testdb"); let filQuery = { name: "Audi" }; let updateQuery = { $set: { "price": 52000 }}; db.collection('cars').updateOne(filQuery, updateQuery).then(result => { console.log('Car updated'); console.log(result); }).catch((err) => { console.log(err); }).finally(() => { client.close(); }); }); ``` 该示例更新了汽车的价格。 ```js let filQuery = { name: "Audi" }; let updateQuery = { $set: { "price": 52000 }}; db.collection('cars').updateOne(filQuery, updateQuery).then(result => { ``` 通过`updateOne()`方法将 Audi 的价格更改为 52,000。 `$set`运算符用于更改价格。 ```js > db.cars.find({name:'Audi'}) { "_id" : ObjectId("5cfcfc3438f62aaa09b52175"), "name" : "Audi", "price" : 52000 } ``` 我们使用`mongo`工具确认更改。 在本教程中,我们使用了 MongoDB 和 JavaScript。 列出[所有 JavaScript](/all/#js) 教程。