nodejs操作MongoDB数据库 MongoDB增、删、改、查
nodejs、MongoDB相关介绍请自行了解。
使用环境
- "node": "^10.16.0"
- "mongodb": "^3.6.0"
操作流程
其实很简单,如果想对数据库进行操作,肯定要先连接数据库吧,连接完数据库肯定要找要操作的数据表吧,找到数据表了,是不是就可以对数据表进行增、删、改、查了!更全的英文文档请访问mongodb.com
具体操作
安装MongoDB
安装MongoDB
npm install mongodb --save
引入 mongodb下面的连接模块MongoClient
// 引入MongoDB 连接模块
const MongoClient = MongoDB.MongoClient;
连接数据库
// 数据库地址
let url = "mongodb://localhost:27017/";
MongoClient.connect(url,(err,client)=>{
if(err){
console.log(err);
return false;
}
});
关闭连接数据库
MongoClient.connect(url, function (err, client) {
// 执行数据库操作
...code
// 关闭连接数据库
client.close();
});
创建集合实例
如果你对数据库和集合的概念不理解的话,电脑上的Excel文件用过吧,一个Excel文件里是不是有多个sheet表,对应的一个数据库里也可以有多个集合(MySQL里面叫表,MongoDB里叫集合)。
mongodb当集合不存在时,会自动创建集合,因此,可以不用特意的进行集合的创建操作
const MongoClient = require("mongodb").MongoClient;
const url = "xxxxxxxx";
MongoClient.connect(url, function (err, client) {
client
.db("example") // 连接example数据库
.createCollection("table1") // 创建一个table1集合实例,如果集合不存在,会自动创建集合
.then(
function (result) {},
function (err) {
console.log(err.message);
}
);
});
Node.js中创建一个Collection对象实例的方法:
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://localhost:27017",function(err,db){
dbo = db.db("test");
collectionIns = dbo.collection("products");
console.log(collectionIns);
db.close();
});
其中 collectionIns是一个collection对象实例,Collection对象实例有很非常多的方法可以使用,下文举例一些实例方法。
获取所有集合
const MongoClient = require("mongodb").MongoClient;
const url = "";
MongoClient.connect(url, function (err, client) {
client.db("example").listCollections().toArray().then(function (tables) {
tables.forEach(function (value, index, ts) {
console.log(value.name);
})
}, function (err) {
console.log(err.message);
})
});
包装ID
通过id对数据操作的时候需要用到此方法,MongoDB里面查询_id ,把字符串转换成对象,MongoDB数据库里的_id是自动生成的,通过dind方法查询结果可以看到形式如: {"_id": ObjectId("5aad299bc166236421c99d229")}
,直接传入5aad299bc166236421c99d229
,是查询不到结果的,所以需要包装一下
// 引入MongoDB 模块
const MongoDB = require("mongodb");
// 引入MongoDB 连接模块
const MongoClient = MongoDB.MongoClient;
// 引入MongoDB ObjectID模块
const ObjectID = MongoDB.ObjectID;
let _id = new ObjectID("5bcae50ed1f2c2f5e4e1a76a");
db.collection('xxx').find({
"_id": _id
}).forEach(function (item) {
console.log(item)
})
向集合中插入一条数据
insertOne(json)
:插入一条数据json格式
MongoClient.connect(url, function (err, client) {
client
.db("example")
.collection("table1")
.insertOne({ name: "张三丰11" })
.then(
function (result) {},
function (err) {
console.log(err.message);
}
);
});
向集合中批量插入一组数据,数组里的每一个对象都是一条数据,会有各自的_id索引
insertMany(array)
:插入一组数据array格式
MongoClient.connect(url, function (err, client) {
client
.db("example")
.collection("table1")
.insertMany([
{ name: "张红2" },
{ name: "张红3" },
{ name: "张红4" },
{ name: "张红5" },
])
.then(
function (result) {},
function (err) {
console.log(err.message);
}
);
});
向集合中删除一条数据
removeOne(json)
:插入一组数据json格式
如果集合中有多个name是张三丰的,默认只会删除第一条数据。
MongoClient.connect(url, function (err, client) {
client
.db("example")
.collection("table1")
.removeOne({ name: "张三丰" })
.then(
function (result) {},
function (err) {
console.log(err.message);
}
);
});
向集合中批量删除一组数据
deleteMany(json)
:插入一组数据json格式,符合条件的都会被删除。
MongoClient.connect(url, function (err, client) {
client
.db("example")
.collection("table1")
.deleteMany({ name: "张三丰" })
.then(
function (result) {},
function (err) {
console.log(err.message);
}
);
});
向集合中修改一条数据
updateOne(json, { $set: newJson })
: json需要更新数据的条件,newJson新数据的内容
如果集合中有多个name是张三丰的,默认只会删除第一条数据。
MongoClient.connect(url, function (err, client) {
client
.db("example")
.collection("table1")
.updateOne({ name: "张三丰" }, {
$set: { name: "小鱼儿"},
})
.then(
function (result) {},
function (err) {
console.log(err.message);
}
);
});
.updata
方法针对不同的数据有不同的运算符可以直接使用,方便快捷。
字段更新运算符
字段更新运算符:
$inc
: 增加指定字段的值$mul
: 将字段的值乘以数字$rename
: 更新一个字段的名称$setOnInsert
: 插入数据默认值$set
: 设置一个字段的值$unset
: 删除某个字段$min
: 赋值最小值$max
: 赋值最大值$currentDate
: 日期操作
详情请访问英文官网
$inc
增加指定字段的值
例如:
有这样一个数据
{
_id: 1,
sku: "abc123",
quantity: 10,
metrics: {
orders: 2,
ratings: 3.5
}
}
以下updateOne()
操作使用 $inc
运算符将quantity
字段减小2 (即增加-2),并将metrics.orders
字段增大1:
db.products.updateOne(
{ sku: "abc123" },
{ $inc: { quantity: -2, "metrics.orders": 1 } }
)
更新后的文档类似于:
{
"_id" : 1,
"sku" : "abc123",
"quantity" : 8,
"metrics" : {
"orders" : 3,
"ratings" : 3.5
}
}
$mul
将字段的值乘以数字
例如:
有这样一个数据
{ _id: 1, item: "ABC", price: 10.99 }
以下updateOne()
操作使用 $mul
运算符将price
字段乘以1.25
db.products.updateOne(
{ _id: 1 },
{ $mul: { price: 1.25 } }
)
更新后的文档类似于:
{ _id: 1, item: "ABC", price: 13.7375 }
$rename
更新一个字段的名称
例如:
有这样一个数据
{
"_id": 1,
"alias": [ "The American Cincinnatus", "The American Fabius" ],
"mobile": "555-555-5555",
"nmae": { "first" : "george", "last" : "washington" }
}
{
"_id": 2,
"alias": [ "My dearest friend" ],
"mobile": "222-222-2222",
"nmae": { "first" : "abigail", "last" : "adams" }
}
{
"_id": 3,
"alias": [ "Amazing grace" ],
"mobile": "111-111-1111",
"nmae": { "first" : "grace", "last" : "hopper" }
}
此操作将字段重命名nmae
为name
。
db.students.updateMany( {}, { $rename: { "nmae": "name" } } )
如果属性是一个对象里面的属性,使用对象属性的写法,如:
db.students.update( { _id: 1 }, { $rename: { "name.first": "name.fname" } } )
更新后的文档类似于:
{
"_id": 1,
"alias": [ "The American Cincinnatus", "The American Fabius" ],
"mobile": "555-555-5555",
"name": { "first" : "george", "last" : "washington" }
}
{
"_id" : 2,
"alias" : [ "My dearest friend" ],
"mobile" : "222-222-2222",
"name" : { "first" : "abigail", "last" : "adams" }
}
{ "_id" : 3,
"alias" : [ "Amazing grace" ],
"mobile" : "111-111-1111",
"name" : { "first" : "grace", "last" : "hopper" } }
$setOnInsert
插入数据默认值
如果upsert:true
的时候,更新操作导致的是新插入的文档,之前没有过这个数据的,则$setOnInsert
将指定的值分配给文档中的字段,也就是$setOnInsert
才会生效。如果更新操作没有导致插入新文档,也就是在旧的数据上进行修改,则$setOnInsert
不执行任何操作。
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
例如:
以下updateOne()
操作使用 $setOnInsert
更新
db.products.updateOne(
{ _id: 1 },
{
$set: { item: "apple" },
$setOnInsert: { defaultQty: 100 }
},
{ upsert: true }
)
更新后的文档类似于:
{ "_id" : 1, "item" : "apple", "defaultQty" : 100 }
$set
设置一个字段的值
例如:
有这样一个数据
{
_id: 100,
sku: "abc123",
quantity: 250,
instock: true,
reorder: false,
details: { model: "14Q2", make: "xyz" },
tags: [ "apparel", "clothing" ],
ratings: [ { by: "ijk", rating: 4 } ]
}
对于符合_id等于的条件的文档100,以下操作将使用$set运算符来更新quantity字段,details字段和tags 字段的值。
db.products.updateOne(
{ _id: 100 },
{ $set:
{
quantity: 500,
details: { model: "14Q3", make: "xyz" },
tags: [ "coats", "outerwear", "clothing" ]
}
}
)
该操作将以下值替换为:quantityto 500; 该 details字段到一个新的嵌入的文档,并且tags字段到一个新的数组。
$unset
删除某个字段,如果字段不存在,则不会影响操作
例如:
以下updateOne()
操作使用 $unset
删除quantity和instock两个字段
db.products.updateOne(
{ sku: "unknown" },
{ $unset: { quantity: "", instock: "" } }
)
$min
赋值最小数
如果指定的值小于字段的当前值,min运算符可以使用BSON比较顺序比较不同类型的值。
简单的说就是如果新值比旧值小的时候才会生效,否则不会更新。
例如:
原数据
{ _id: 1, highScore: 800, lowScore: 200 }
以下updateOne()
操作使用 $min
更新lowScore的值为150,只有新值比旧值小的时候才会生效,否则不会更新
db.products.updateOne(
{ _id: 1 }, { $min: { lowScore: 150 } }
)
$max
赋值最大数
如果指定的值大于字段的当前值,max运算符可以使用BSON比较顺序比较不同类型的值。
简单的说就是如果新值比旧值大的时候才会生效,否则不会更新。
例如:
原数据
{ _id: 1, highScore: 800, lowScore: 200 }
以下updateOne()
操作使用 $max
更新highScore的值为950,只有新值比旧值大的时候才会生效,否则不会更新
db.products.updateOne(
{ _id: 1 }, { $max: { highScore: 950 } }
)
数组更新运算符
数组更新运算符:
$
:$addToSet
:$pop
:$pullAll
:$pull
:$pushAll
:$push
:$each
:$slice
:$sort
:$position
:
$
$addToSet
$pop
$pullAll
$pull
$pushAll
$push
$each
$slice
$sort
$position
向集合中批量修改一组数据
updateMany(json, { $set: newJson })
: json需要更新数据的条件,newJson新数据的内容。只要符合条件的数据都会被修改更新。
MongoClient.connect(url, function (err, client) {
client
.db("example")
.collection("table1")
.updateMany({ name: "张三丰" }, {
$set: { name: "小鱼儿"},
})
.then(
function (result) {},
function (err) {
console.log(err.message);
}
);
});
获取集合中的一组数据
find(json,projection)
: json是需要更新数据的条件。只要符合条件的数据都会被返回,{}
是返回所有数据,projection是可选项,指定匹配数据中返回哪些字段,{ projection: { article_id: 1, name: 0 }
, 1
或true
是显示字段,0
或false
是不显示,。
注意:
find({}, { projection: { article_id: 1 }})
要这样写,官网都没有写成{ projection: {xxxx}}
这样,所以一直没有生效,有可能是MongoDB版本问题吧
MongoClient.connect(url, function (err, client) {
client
.db("example")
.collection("table1")
.find({ name: "张三丰" })
.toArray()
.then(
function (result) {
result.forEach(function (value, index, arr) {
console.log(value);
});
},
function (err) {
console.log(err.message);
}
);
});
db.集合名.count():指定集合文档数量
db.集合名.find().count() : 根据条件查找数量
db.集合名.find({userName:/张/}):模糊查找。查找名字当中包含常
db.集合名.find({age:{$gt:12}}):查找年龄大于12
$gt:大于
$gte:大于等于
$lt:小于
$lte:小于等于
$ne:不等于
db.集合名.find({age:{$ne:12},sex:"女"}):多条件,年龄不等于12,性别为女
或
db.集合名.find({$or:[{sex:"女"},{age:12}]}):查找性别为女,或年龄为12的记录
db.集合名.find().skip(2):跳指指定的文档数(跳过前两行文档)
db.集合名.find().limit(3):取指定的文档数(取前三行文档)
db.集合名.find().sort({age:-1}):按照年龄的倒序。1正序,-1倒序
db.集合名.find().sort({age:-1,"score.yuwen":1}):按照年龄的倒序,如果年龄相同,按照语文的正序
db.集合名.findAndModify(query,sort,update,[options],callback)
对于query参数匹配的文档进行修改。sort参数确定哪些对象先被修改。update参数指定要在文档上进行的更改,回调函数接收err,res
db.集合名.findAndRemove(query,sort,[options],callback)
删除与query匹配的字符串,sort决定哪些字符串先被修改,callback接收err和res
db.集合名.distinct(key,[query],callback)
在集合中为一个特定的文档key创建不同的值的列表。如果指定query参数那么只有与query匹配的文档在内。回调函数接受error,values
db.集合名.count([query],callback)
计算集合中文档的数量,
db.集合名.drop(callback)
删除当前集合
db.集合名.stats(callback)
获取集合的统计信息,包括条目数量,在磁盘上的大小,平均对象大小,以及更多的信息。
分页操作
已知:
1、pageIndex:指定的页数
2、count:文档数量
3、pageSum:总页数 pageSum = Math.ceil(count/pageNum)
4、pageNum:每页显示的条数
求:
每页要显示的内容。
问:总条数9,每页2条,每一页的内容如何求
skip = (pageIndex-1)*pageNum;
1、 db.score.find().sort({age:-1}).skip(0).limit(2)
2、 db.score.find().sort({age:-1}).skip(2).limit(2)
3、 db.score.find().sort({age:-1}).skip(4).limit(2)
4、 db.score.find().sort({age:-1}).skip(6).limit(2)
4、 db.score.find().sort({age:-1}).skip(8).limit(2)
获取集合中的全部数据
find(json)
: json需要更新数据的条件。只要符合条件的数据都会被返回。
只要传入的json是个空对象,就会返回所有数据了
MongoClient.connect(url, function (err, client) {
client
.db("example")
.collection("table1")
.find({})
.toArray()
.then(
function (result) {
result.forEach(function (value, index, arr) {
console.log(value);
});
},
function (err) {
console.log(err.message);
}
);
});
读取大于100条数据的时候会出现报错官网解释,可以尝试用forEach
代替
MongoClient.connect(url, function (err, client) {
client
.db("example")
.collection("table1")
.find({})
.forEach()
.then(
function (result) {
result.forEach(function (value, index, arr) {
console.log(value);
});
},
function (err) {
console.log(err.message);
}
);
});
封装的操作MongoDB库
/*
封装DB库操作
*/
// 引入MongoDB 模块
const MongoDB = require("mongodb");
// 引入MongoDB 连接模块
const MongoClient = MongoDB.MongoClient;
// 引入MongoDB ObjectID模块
const ObjectID = MongoDB.ObjectID;
// 引入配置文件
const Config = require("./MongoDB.config.js");
class Db {
// 单例模式,解决多次实例化时候每次创建连接对象不共享的问题,实现共享连接数据库状态
static getInstance() {
if (!Db.instance) {
Db.instance = new Db();
}
return Db.instance;
}
constructor() {
// 属性 存放db对象
this.dbClient = "";
// 实例化的时候就连接数据库,增加连接数据库速度
this.connect();
}
// 连接数据库
connect() {
return new Promise((resolve, reject) => {
// 解决数据库多次连接的问题,要不然每次操作数据都会进行一次连接数据库的操作,比较慢
if (!this.dbClient) {
// 第一次的时候连接数据库
MongoClient.connect(Config.dbUrl, (err, client) => {
if (err) {
reject(err);
} else {
// 将连接数据库的状态赋值给属性,保持长连接状态
this.dbClient = client.db(Config.dbName);
resolve(this.dbClient);
}
});
} else {
// 第二次之后直接返回dbClient
resolve(this.dbClient);
}
});
}
/**
* 查询数据库
* 使用方法: let result = await DB.find('user',{});
* @param {String} collectionName 集合名称、数据表名
* @param {Object} json 查询的条件
*/
find(collectionName, json) {
return new Promise((resolve, reject) => {
this.connect().then((db) => {
// 操作db库里的某一个表,返回符合条件的内容,json查找的条件
let result = db.collection(collectionName).find(json);
result.toArray(function (err, docs) {
if (err) {
reject(err);
return;
}
resolve(docs);
});
});
});
}
/**
* 更新数据库,多个符合条件的只会更新第一条数据
* 使用方法: let result = await DB.update('user',{'username':'lisi'},{'username':'李四'});
* @param {String} collectionName 集合名称、数据表名
* @param {Object} json1 需要更新数据的条件
* @param {Object} json2 新数据的内容
*/
update(collectionName, json1, json2) {
return new Promise((resolve, reject) => {
this.connect().then((db) => {
// 操作db库里的某一个表,更新一条数据,json1查找的内容,json2更新的新内容,回调函数
db.collection(collectionName).updateOne(
json1,
{
$set: json2,
},
(err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
}
);
});
});
}
/**
* 更新数据库,所有符合条件的都会被更新
* 使用方法: let result = await DB.updateMany('user',{'username':'lisi'},{'username':'李四'});
* @param {String} collectionName 集合名称、数据表名
* @param {Object} json1 需要更新数据的条件
* @param {Object} json2 新数据的内容
*/
updateMany(collectionName, json1, json2) {
return new Promise((resolve, reject) => {
this.connect().then((db) => {
// 操作db库里的某一个表,更新一条数据,json1查找的内容,json2更新的新内容,回调函数
db.collection(collectionName).updateMany(
json1,
{
$set: json2,
},
(err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
}
);
});
});
}
/**
* 插入数据库
* 使用方法: let result = await DB.insert('user',{'username':'赵六666','age':30,'sex':'女','status':'2'});
* @param {String} collectionName 集合名称、数据表名
* @param {Object} json 插入的新数据
*/
insert(collectionName, json) {
return new Promise((resolve, reject) => {
this.connect().then((db) => {
// 操作db库里的某一个表,插入一条数据,json插入的新内容,回调函数
db.collection(collectionName).insertOne(json, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
});
}
/**
* 批量插入数据库,数组里的每一个对象都是一条数据,会有各自的_id索引
* 使用方法: let result = await DB.insertMany('user',[{'username':'赵六666','age':30,'sex':'女','status':'2'},{'username':'赵六666','age':30,'sex':'女','status':'2'},{'username':'赵六666','age':30,'sex':'女','status':'2'}...]);
* @param {String} collectionName 集合名称、数据表名
* @param {Array} json 批量插入的新数据
*/
insertMany(collectionName, arr) {
return new Promise((resolve, reject) => {
this.connect().then((db) => {
// 操作db库里的某一个表,批量插入一组数据,arr批量插入的新内容,回调函数
db.collection(collectionName).insertMany(arr, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
});
}
/**
* 删除数据,多个符合条件的只会删除第一条数据
* 使用方法: let result = await DB.remove('user',{'username':'李四'});
* @param {String} collectionName 集合名称、数据表名
* @param {Object} json 删除数据的条件
*/
remove(collectionName, json) {
return new Promise((resolve, reject) => {
this.connect().then((db) => {
db.collection(collectionName).removeOne(json, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
});
}
/**
* 批量删除一组数据,多个符合条件的都会被删除
* 使用方法: let result = await DB.deleteMany('user',{'username':'李四'});
* @param {String} collectionName 集合名称、数据表名
* @param {Object} json 删除数据的条件
*/
deleteMany(collectionName, json) {
return new Promise((resolve, reject) => {
this.connect().then((db) => {
db.collection(collectionName).deleteMany(json, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
});
}
/**
* 通过id查询数据时候需要用到此方法,MongoDB里面查询_id ,把字符串转换成对象
* MongoDB数据库里的_id是自动生成的,通过dind方法查询结果可以看到形式如: {"_id": ObjectId("5aad299bc166236421c99d229")},直接传入5aad299bc166236421c99d229,是查询不到结果的,所以需要包装一下
* 使用方法: let result = await DB.find('user',{'_id': DB.getObjectID(xxxxx)});
* @param {String} id 要查询的id
*/
getObjectID(id) {
return new ObjectID(id);
}
}
module.exports = Db.getInstance();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具