Home 软件开发 NodeJS使用Mongoose对MongoDB进行增删改查等基本操作 By FreelyTomorrow Dec 27, 2023 5 min read NodeJS使用Mongoose对MongoDB进行增删改查等基本操作 MVC模式下使用Mongoose模块对MongoDB记录进行基本的增删改查操作和筛选,排序。 链接数据库 //导入Mongoose包 const mongoose = require('mongoose'); //链接MongoDB mongoose.connect('mongodb://localhost:27017/bilibili'); //设置回调 mongoose.connection.once('open', () => { console.log('链接数据库成功'); }); mongoose.connection.once('error', () => { console.log('链接数据库失败'); }); mongoose.connection.once('close', () => { console.log('和数据库的链接中断'); }); setTimeout(() => { mongoose.disconnect(); }, 2000); once和on的区别在于once只会执行一次回调函数,而on会每次都执行,如果将端口侦听写在回调中,则一定要用once。 创建新文档 mongoose.connection.once('open', () => { console.log('链接数据库成功'); //创建文档的结构对象,设置集合中文档的属性以及属性值类型 let bookSchema = new mongoose.Schema({ name: String, author: String, price: Number }); //创建模型对象,即对之前的文档操作的封装对象 let bookModel = mongoose.model('books', bookSchema); //新增 createBook(bookModel); //bookModel.create({name: '西游记', author: '吴承恩',price: 19.9}); }); 异步执行写入操作,返回插入数据对象本身。 这里原本可以卸载create的回调函数中,但是从Mongoose7开始create方法不在支持回调函数,因此只能通过异步操作方式获得返回对象。 async function createBook(bookModel){ try{ const data = await bookModel.create({ name: '红楼梦', author: '曹雪芹', price: 19.9 }); console.log(data); }catch (err){ console.log(err); } } 字段类型 有以下的数据类型 类型 描述 String 字符串 Number 数字 Boolean 布尔值 Array 数组类型,也可以用[]表示 Date 日期 Buffer Buffer对象,比如多媒体文件的二进制码 Mixed 任意类型,需要使用mongoose.Schema.Types.Mixed指定 ObjectId 对象ID,需要使用mongoose.Schema.Types.ObjectId指定 Decimal128 高精度数字,需要使用mongoose.Schema.Types.Decimal128指定 举例 mongoose.connection.once('open', () => { let bookSchema = new mongoose.Schema({ name: String, author: String, price: Number, isHot: Boolean, tags: Array, publish: Date }); let bookModel = mongoose.model('books', bookSchema); createBook(bookModel); }); async function createBook(bookModel){ const data = await bookModel.create({ name: '红楼梦', author: '曹雪芹', price: 19.9, isHot: true, tags: ['古典', '社会', '情感'], publish: new Date() }); } 字段验证 有以下几种验证方法 类型 作用 required 表示该字段为必填字段 unique 是否为唯一值(必须在新集合中实现) enum 枚举类型,复赋值是必须为枚举类型中所规定的值 default 字段的默认值 举例 mongoose.connection.once('open', () => { let bookSchema = new mongoose.Schema({ id: {type: String, unique: true}, //unique: 是否为唯一值(必须在新集合中实现) name: {type: String, required: true}, //required: 表示该字段为必填字段 author: {type: String, default: 佚名}, //default: 字段的默认值 source: {type: String, enum: ['中文', '外文']}, //enum: 枚举类型,复赋值是必须为枚举类型中所规定的值。 price: Number }); let bookModel = mongoose.model('books', bookSchema); createBook(bookModel); }); 删除文档 基于两个核心方法deleteOne和deleteMany可以分别删除单条文档和多条文档 mongoose.connection.once('open', () => { console.log('链接数据库成功'); let bookSchema = new mongoose.Schema({ name: String, author: String, price: Number, is_hot: Boolean }); let bookModel = mongoose.model('novels', bookSchema); //删除单条 deleteRecords(bookModel, {author: '余华'}, bookModel.deleteOne); //删除多条 deleteRecords(bookModel, {author: '余华'}, bookModel.deleteMany); }); async function deleteRecords(model, query, deleteFunction){ try{ const data = await deleteFunction.call(model, query); console.log(data); }catch(err){ console.log(err); } } 更新文档 基于updateOne和updateMany两个函数 mongoose.connection.once('open', () => { console.log('链接数据库成功'); let bookSchema = new mongoose.Schema({ name: String, author: String, price: Number, is_hot: Boolean }); let bookModel = mongoose.model('novel', bookSchema); updateRecords(bookModel, {name: '西游记'}, bookModel.updateOne, {price: 50}); }); async function updateRecords(model, query, update, newRecord){ try{ const data = await update.call(model, query, newRecord); console.log(data); }catch(err){ console.log(err); } } 读取文档 同样,基于One和Many两个函数 async function findRecords(model, query, search){ try{ const data = await search.call(model, query); console.log(data); }catch(err){ console.log('读取失败: ', err); return; } } 调用 findRecords(bookModel, {author: '曹雪芹'}, bookModel.findOne); findRecords(bookModel, {author: '余华'}, bookModel.findMany); 条件控制 就像if else可以通过与和或将多个条件结合使用一样,mongodb也可以;MongoDB中有以下几种条件控制 运算符 运算符 作用 $gt 大于 $lt 小于 $gte 大于等于 $lte 小于等于 $ne 不等于 举例: findRecords(bookModel, {price: {$lt: 20}}, bookModel.findOne); 逻辑运算 运算符 作用 $or 或运算 $and 与运算 举例: findRecords(bookModel, { $and: [ {price: {$gt: 30}}, {price: {$lt: 70}} ] }, bookModel.findOne); 正则匹配 有两种方法 findRecords(bookModel,{name: /三/}, bookModel.findOne); //另一种方法: findRecords(bookModel,{name: new RegExp('三')}, bookModel.findOne); 推荐使用第二种,因为第一种无法读取变量。 个性化读取 有以下几种方法,可以显示特定的文档 方法 作用 select 字段筛选 sort 排序 skip 跳过多少条记录 limit 向后显示多少条记录 使用方法: //只显示返回的数据的name和author两个字段, 不显示_id字段 const data = await model.find(query).select({name: 1, author: 1, _id: 0}); //根据返回数据的price字段升序显示(-1为降序) const data = await model.find(query).sort({price: 1}).select({name: 1, price: 1}); //只返回数据的前三条 const data = await model.find(query).sort({price: 1}).select({name: 1, price: 1}).limit(3); //和skip组合使用 //只返回第3到第6条数据 const data = await model.find(query).sort({price: 1}).select({name: 1, price: 1}).skip(3).limit(3); findRecords(bookModel, { $and: [ {price: {$gt: 30}}, {price: {$lt: 70}} ] }, bookModel.findOne); Read Next By FreelyTomorrow May 9, 2024 事件源模式和传统数据库方法在数据管理上的优劣分析 对事件源模式和传统数据库方法在应用程序性能影响、性能、扩展性和可靠性的分析;以及云原生环境下数据管理的最佳实践 云原生 By FreelyTomorrow Apr 5, 2024 关于IP、子网掩码、主机位和网络位的计算方法 如何通过子网掩码和掩码位计算一个IP地址的网络地址和可分配的主机位 网络 By FreelyTomorrow Mar 14, 2024 交换机的工作原理 - 学习、泛洪、转发和过滤 交换机的工作原理,包括学习、泛洪、转发和过滤四个过程;如何使用MAC地址来管理网络数据流,如何通过与设备的互动来建立和更新地址表。 网络 By FreelyTomorrow Feb 21, 2024 提升网站安全性和安全评估等级的方法 介绍了通过禁用TSL1.0和启用HSTS策略提升网站安全性的两种方法。 网络 运维技术
By FreelyTomorrow May 9, 2024 事件源模式和传统数据库方法在数据管理上的优劣分析 对事件源模式和传统数据库方法在应用程序性能影响、性能、扩展性和可靠性的分析;以及云原生环境下数据管理的最佳实践 云原生
By FreelyTomorrow Mar 14, 2024 交换机的工作原理 - 学习、泛洪、转发和过滤 交换机的工作原理,包括学习、泛洪、转发和过滤四个过程;如何使用MAC地址来管理网络数据流,如何通过与设备的互动来建立和更新地址表。 网络
链接数据库
once和on的区别在于once只会执行一次回调函数,而on会每次都执行,如果将端口侦听写在回调中,则一定要用once。
创建新文档
异步执行写入操作,返回插入数据对象本身。
这里原本可以卸载create的回调函数中,但是从Mongoose7开始create方法不在支持回调函数,因此只能通过异步操作方式获得返回对象。
字段类型
有以下的数据类型
举例
字段验证
有以下几种验证方法
举例
删除文档
基于两个核心方法deleteOne和deleteMany可以分别删除单条文档和多条文档
更新文档
基于updateOne和updateMany两个函数
读取文档
同样,基于One和Many两个函数
调用
条件控制
就像if else可以通过与和或将多个条件结合使用一样,mongodb也可以;MongoDB中有以下几种条件控制
运算符
举例:
逻辑运算
举例:
正则匹配
有两种方法
推荐使用第二种,因为第一种无法读取变量。
个性化读取
有以下几种方法,可以显示特定的文档
使用方法:
Read Next
事件源模式和传统数据库方法在数据管理上的优劣分析
对事件源模式和传统数据库方法在应用程序性能影响、性能、扩展性和可靠性的分析;以及云原生环境下数据管理的最佳实践
关于IP、子网掩码、主机位和网络位的计算方法
如何通过子网掩码和掩码位计算一个IP地址的网络地址和可分配的主机位
交换机的工作原理 - 学习、泛洪、转发和过滤
交换机的工作原理,包括学习、泛洪、转发和过滤四个过程;如何使用MAC地址来管理网络数据流,如何通过与设备的互动来建立和更新地址表。
提升网站安全性和安全评估等级的方法
介绍了通过禁用TSL1.0和启用HSTS策略提升网站安全性的两种方法。