MongoDB JavaScript 教程展示了如何在 JavaScript 中创建使用 MongoDB 的程序。本教程使用本机 mongodb 驱动程序。 (还有其他解决方案,例如 Mongoose 或 Monk。)
MongoDB
MongoDB 是一个 NoSQL 跨平台的面向文档的数据库。它是可用的最流行的数据库之一。 MongoDB 由 MongoDBInc 开发。并作为免费和开源软件发布。
record在MongoDB中就是一个文档,它是由字段和值对组成的数据结构。 MongoDB 文档 类似于 JSONobjects。字段的值可能包括其他文档、数组、文档数组。 MongoDB 将文档存储在集合中。 集合 类似于关系数据库中的表和文档行的区域
安装 MongoDB 服务器
以下命令可用于在基于 Debian 的 Linux 上安装 MongoDB。
$ sudo apt-get install mongodb
该命令安装 MongoDB 附带的必要包。
$ sudo service mongodb status mongodb start/running, process 975
使用sudo service mongodb status
命令我们检查mongodb
服务器的状态。
$ sudo service mongodb start mongodb start/running, process 6448
mongodb
服务器使用sudo service mongodbstart
命令启动。
安装MongoDB驱动
我们设置了项目。
$ npm i mongodb
我们安装mongodb
本机JavaScript 驱动程序。 npm
是一个 Node.js 包管理器。 MongoDB Node.js 驱动程序提供基于回调和基于 Promised 的交互。
MongoDB 创建数据库
mongo
工具是 MongoDB 的交互式 JavaScript shell 接口,它为系统管理员提供了一个接口,也为开发人员提供了一种直接使用数据库测试查询和操作的方法。
$ 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 是一个用于延迟和异步计算的对象。它代表一个尚未完成但预期在未来完成的操作。
asyncFunc() .then(value => { /* success */ }) .catch(error => { /* failure */ }) .finally( => { /* cleanup */};
then
方法总是返回一个 Promise,这使我们能够链接方法调用。
我们还可以使用 async/await
语法来处理 promises。
MongoDB JS 驱动
在第一个示例中,我们打印了 Node.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(); });
在示例中,我们连接到服务器并查找客户端信息。
const mongo = require('mongodb');
我们使用mongodb
模块。
const client = mongo.MongoClient;
MongoClient
用于连接MongoDB服务器。
const url = 'mongodb://localhost:27017';
这是数据库的 URL。 27017 是 MongoDB 服务器监听的默认端口。
MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => {
使用connect
创建到数据库的连接。
$ 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
方法列出数据库中的可用集合。
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
数据库并检索其所有集合。
db.listCollections().toArray().then((docs) => { console.log('Available collections:'); docs.forEach((doc, idx, array) => { console.log(doc.name) }); ...
listCollection
方法查找testdb
数据库中的所有集合;它们被打印到控制台。
}).catch((err) => { console.log(err); }).finally(() => { client.close(); });
在catch
块中,我们捕获任何潜在的异常,并在finally
块中关闭与数据库的连接。
$ node list_collections.js Available collections: continents cars cities
在我们的数据库中,我们有这三个集合。
MongoDB 数据库统计信息
dbstats
方法获取数据库的统计信息。
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
数据库并显示其统计信息。
$ 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 的结果。
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
集合中检索所有文档。
db.collection('cars').find({}).toArray().then((docs) => {
传递空查询将返回所有文档。
$ 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
函数返回集合中匹配文档的数量。
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
集合中的文档数。
$ node count_documents.js There are 8 documents
现在 cars 集合中有八个文档。
MongoDB findOne
findOne
方法返回一个满足指定查询条件的文档。如果有多个文档满足查询,该方法按照反映文档在磁盘上的顺序的自然顺序返回第一个文档。
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
集合中读取一个文档。
let query = { name: 'Volkswagen' }
查询包含汽车的名称âVolkswagen。
collection.findOne(query).then(doc => {
查询被传递给findOne
方法。
$ node find_one.js { _id: 8, name: 'Volkswagen', price: 21600 }
MongoDB 异步/等待示例
使用async/await
,我们可以轻松地以同步方式处理 promises。
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
读取一个文档。
async function findCar() {
函数有async
关键字。
let res = await collection.findOne(query);
使用await
,我们等待findOne
函数的结果。
MongoDB 查询运算符
可以使用 $gt
、$lt
或 $ne
等 MongoDB 查询运算符过滤数据。
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 的文档。
let query = { price: { $gts: 30000 } };
$gt
运算符用于获取价格大于 30,000 的汽车。
$ 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 } ]
这是示例的输出。只包括3万以上的车。
$and
逻辑运算符可用于组合多个表达式。
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 之间的汽车。
let query = { $and: [{ price: { $gt: 20000 } }, { price: { $lt: 50000 } }] };
$and
运算符结合$gt
和$lt
得到结果。
$ 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 预测
投影确定从数据库传递哪些字段。
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
字段。
db.collection('cars').find({}).project({_id: 0}).toArray().then((docs) => {
project
方法为查询设置投影; itex 不包括_id
字段。
$ 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
方法指定要跳过的文档数。
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
集合中读取,跳过前两个文档,并将输出限制为五个文档。
db.collection('cars').find({}).skip(2).limit(5).toArray().then((docs) => {
skip
方法跳过前两个文档,limit
方法将输出限制为五个文档。
$ 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 聚合
聚合计算集合中数据的聚合值。
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(); }); });
该示例计算集合中所有汽车的价格。
let myagr = [{$group: {_id: 1, all: { $sum: "$price" } }}];
$sum
运算符计算并返回数值的总和。$group
运算符按指定的标识符表达式对输入文档进行分组,并将累加器表达式(如果指定)应用于每个组。
db.collection('cars').aggregate(myagr).toArray().then((sum) => {
aggregate
函数对cars
集合应用聚合操作。
$ node sum_all_cars.js [ { _id: 1, all: 581769 } ]
所有价格的总和是 581,769。
我们可以使用$match
运算符来选择特定的汽车进行聚合。
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(); }); });
该示例计算奥迪和沃尔沃汽车的价格总和。
let myagr = [ { $match: { $or: [{ name: "Audi" }, { name: "Volvo" }] } }, { $group: { _id: 1, sum2cars: { $sum: "$price" } } } ];
表达式使用$match
、$or
、$group
和$sum
运算符来完成任务。
$ node sum_two_cars.js [ { _id: 1, sum2cars: 81642 } ]
两车价格总和为81642。
MongoDB insertOne
insertOne
方法将单个文档插入到集合中。
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(); }); });
该示例将一辆汽车插入汽车集合。
let doc = {_id: new ObjectID(), name: "Toyota", price: 37600 };
这是一个要插入的文件。使用ObjectID
生成一个新的 Id。
db.collection('cars').insertOne(doc).then((doc) => {
insertOne
函数将文档插入到集合中。
> db.cars.find({name:'Toyota'}) { "_id" : ObjectId("5d03d4321f9c262a50e671ee"), "name" : "Toyota", "price" : 37600 }
我们使用mongo
工具确认插入。
MongoDB insertMany
insertMany
函数将多个文档插入到一个集合中。
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
集合并向其中插入六个文档。
let collection = db.collection('continents');
collection
方法检索一个集合;如果集合不存在,则创建它。
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,它是一个唯一的值,用于标识文档而不是整数。
collection.insertMany(continents).then(result => { console.log("documents inserted into the collection"); }).catch((err) => { console.log(err); }).finally(() => { client.close(); });
insertMany
方法将文档数组插入continents
集合。
> 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
方法用于删除文档。
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(); }); });
示例删除文档。
let query = { name: "Volkswagen" }; db.collection('cars').deleteOne(query).then((result) => { ...
deleteOne
删除Volkswagen
的文件。
MongoDB updateOne
updateOne
函数用于更新文档。
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(); }); });
该示例更新了汽车的价格。
let filQuery = { name: "Audi" }; let updateQuery = { $set: { "price": 52000 }}; db.collection('cars').updateOne(filQuery, updateQuery).then(result => {
用updateOne
方法把奥迪的价格改成52000,$set
操作符用来改价格。
> db.cars.find({name:'Audi'}) { "_id" : ObjectId("5cfcfc3438f62aaa09b52175"), "name" : "Audi", "price" : 52000 }
我们使用mongo
工具确认更改。
在本文中,我们使用了 MongoDB 和 JavaScript。
列出所有 JavaScript 教程。