当前位置: 首页 > news >正文

Mongoose连接数据库操作实践

文章目录

    • 介绍
    • 特点:
    • Mongoose 使用:
      • 创建项目并安装:
      • 连接到 MongoDB:
      • 定义 Schema:
      • 创建模型并操作数据库:
      • 创建文档:
      • 查询文档:
      • 更新文档:
      • 删除文档:
      • 使用钩子(Hooks):
      • 数据验证:
      • 使用虚拟属性(Virtuals)
      • 设置选项:

介绍

Mongoose 是一个 MongoDB 对象模型库(ODM),它为 Node.js 应用程序提供了一个直白、简洁和富有表现力的数据建模工具.

特点:

  • Mongoose 通过定义模型(Model),这些模型对应于 MongoDB 中的集合(Collection)。
  • Mongoose 通过定义结构(Schema),你可以指定集合中文档(Document)的结构和类型。
  • Mongoose 提供了强大的数据验证机制,确保在保存到数据库之前,数据符合预定义的模式和规则。
  • Mongoose 允许你在数据保存或查询之前或之后执行中间件,这可以用来执行如数据加密、日志记录等操作。
  • Mongoose 支持虚拟属性,这些属性在 MongoDB 中不存储,但可以在应用层使用,常用于计算字段或隐藏某些字段。
  • Mongoose 提供了多个生命周期钩子,如 savevalidateindex 等,允许你在文档的生命周期中的特定点执行自定义代码。

Mongoose 使用:

api 使用操作详见上一篇文章

先介绍下 mongoose 的一些概念、然后以常见功能开发,来举例实现一些 api 介绍,如子文档嵌套、关联查询、查询密码隐藏、默认值设置、MD5 加密、文档数组更新

创建项目并安装:

在 Node.js 项目中,你可以通过 npm 来安装 Mongoose , crypto-js包方便我们进行密码的加密,也可以用 node 自己的 crypto


mkdir mongoose-demo && cd  mongoose-demopnpm initpnpm init mongoose crypto-js

连接到 MongoDB:

创建 main.js,在文件中引入 mongoose , 调用其 connect 进行连接,可使用用户名密码或直接连接

// 直连
await mongoose.connect('mongodb://127.0.0.1:27017/test')
// 添加用户认证
await mongoose.connect('mongodb://root:123456@localhost:8017/test?authSource=admin')
const mongoose = require('mongoose')const connect = async () => {try {db = await mongoose.connect('mongodb://root:123456@localhost:8017/test?authSource=admin')console.log('Connected to MongoDB')} catch (error) {console.log(error.message)}
}
// 调用
connect()

定义 Schema:

  • 在这里使用 Schema 定义 MongoDB 集合的结构,在这里我们定义一个用户结构 (UserSchema) 和地址结构(AddrSchema):

  • 这里使用 default设置字段默认值,使用select来设置在 findfindOne的返回结构中是否展示,避免将密码等敏感字符暴露出接口,
    使用set方法,在数据保存进库之前进行一些操作(如加密),

  • 使用 ref 来进行嵌套子文档查询,这里的user是 model 的名称,不是 Schema

  • 这里我们使用 children 来进行一对多的查询

const UserSchema = new mongoose.Schema({name: String,age: String,phone: {type: String,default: '1848****222' // 设置默认值},password: {type: String,// select: false,set: val => {return Crypto.MD5(val)}},children: [{type: mongoose.Schema.Types.ObjectId,ref: 'addr'}]
})
const AddrSchema = new mongoose.Schema({province: String,city: String,area: String,detail: String,user_id: { type: mongoose.Schema.Types.ObjectId, ref: 'user' }
})

创建模型并操作数据库:

将 Schema 编译成 Model,用于操作数据库:

const userModel = mongoose.model('user', UserSchema, 'users')
const addrModel = mongoose.model('addr', AddrSchema, 'addrs')

创建文档:

使用模型创建文档(即数据库中的记录), 创建add方法,来实现 新增操作

const add = async (name, password) => {try {let user = new userModel({ name, password })let _user = await user.save()console.log('用户保存成功', _user)let addr = new addrModel({province: '四川',city: '成都',area: '高新',user_id: _user._id})let _addr = await addr.save()console.log('地址保存成功', _addr)let update = await userModel.updateOne({ _id: _user._id }, { $push: { children: _addr._id } })console.log('更新成功:', _user._id, _addr._id, update)} catch (error) {console.log(error)}
}const connect = async () => {try {db = await mongoose.connect('mongodb://root:123456@localhost:8017/test?authSource=admin')console.log('Connected to MongoDB')// 在這裡添加操作add('ziyu', 'ziyu')} catch (error) {console.log(error.message)}
}

查询文档:

查询数据库中的文档,新增 query方法,这里用到一个populate方法

Mongoose 的 populate 功能 ‌ 是一种用于填充引用字段的方法,它允许我们在查询结果中获取关联文档的详细信息。使用 populate 方法可以将关联字段的引用值替换为实际的对象值,从而方便地获取关联对象的详细信息。

// find() // 默认查询全部
// findOne() // 查询一个const query = async () => {let findUser = await userModel.findOne({ name: /ziyu/ }).populate('children').exec()console.log('查询用户', findUser)// let findUser = await addrModel.find({}).populate("user_id").exec();// console.log("查询地址", findUser);
}

更新文档:

更新数据库中的文档, 创建update方法

const update = async () => {try {let update = await userModel.updateOne({ _id: '675fd59091847b07acc95fbc' }, { $push: { children: '675fd5b7d62dd41f6e8d88c4' } })console.log('更新成功:', update)} catch (error) {console.log(error)}
}

删除文档:

从数据库中删除文档:

const update = async () => {try {await userModel.deleteOne({ name: 'jty' })console.log('删除成功:', update)} catch (error) {console.log(error)}
}

使用钩子(Hooks):

Mongoose 允许你在文档的生命周期中的特定点执行代码,例如在保存前加密密码:

userSchema.pre('save', function (next) {this.password = Crypto.MD5(this.password)next()
})

数据验证:

Mongoose 提供了强大的数据验证功能,确保保存到数据库的数据是有效的:
userSchema.path('email').validate(function (value) {return validator.isEmail(value)
}, 'Invalid email')

使用虚拟属性(Virtuals)

虚拟属性允许你定义不存储在 MongoDB 中的属性,但可以在查询时使用:
schema.path('name').get(function (v) {return v + ' is my name'
})
schema.set('toJSON', { getters: true })

设置选项:

Mongoose 提供了多种选项来自定义模型的行为,例如 `strict`、`typeKey` 和 `validateBeforeSave`:
cosnt schema = new UserSchema({// ...},{ strict: true, typeKey: '$type', validateBeforeSave: false }
)

相关文章:

Mongoose连接数据库操作实践

文章目录 介绍特点:Mongoose 使用:创建项目并安装:连接到 MongoDB:定义 Schema:创建模型并操作数据库:创建文档:查询文档:更新文档:删除文档:使用钩子&#x…...

centos 7.9 freeswitch1.10.9环境搭建

亲测版本centos 7.9系统–》 freeswitch1.10.9 一、下载插件 yum install -y git alsa-lib-devel autoconf automake bison broadvoice-devel bzip2 curl-devel libdb4-devel e2fsprogs-devel erlang flite-devel g722_1-devel gcc-c++ gdbm-devel gnutls-devel ilbc2...

Gitlab服务管理和仓库项目权限管理

Gitlab服务管理 gitlab-ctl start # 启动所有 gitlab 组件; gitlab-ctl stop # 停止所有 gitlab 组件; gitlab-ctl restart # 重启所有 gitlab 组件; gitlab-ctl status …...

LLMs之Llama-3:Llama-3.3的简介、安装和使用方法、案例应用之详细攻略

LLMs之Llama-3:Llama-3.3的简介、安装和使用方法、案例应用之详细攻略 目录 相关文章 LLMs之LLaMA:LLaMA的简介、安装和使用方法、案例应用之详细攻略 LLMs之LLaMA-2:LLaMA 2的简介(技术细节)、安装、使用方法(开源-免费用于研究和商业用途…...

OpenCV函数及其应用

1. 梯度处理的Sobel算子函数 功能 Sobel算子是一种用于边缘检测的离散微分算子,它结合了高斯平滑和微分求导,用于计算图像亮度的空间梯度。 参数 src:输入图像。 dst:输出图像。 ddepth:输出图像的深度。 dx&#xff…...

vulnhub靶场【DriftingBlues】之3

前言 靶机:DriftingBlues-3,IP地址192.168.1.60 攻击:kali,IP地址192.168.1.16 都采用虚拟机,网卡为桥接模式 主机发现 使用arp-scan -l或netdiscover -r 192.168.1.1/24 信息收集 使用nmap扫描端口 网站探测 访…...

文件上传—阿里云OSS对象存储

目录 一、OSS简介 二、OSS基本使用 1. 注册账号 2. 基本配置 (1) 开通OSS (2) 创建存储空间 (3) 修改权限 (4) 配置完成,上传一张图片,检验是否成功。 (5) 创建AccessKey 三、Java项目集成OSS 1. 导入依赖 2. Result.java代码: …...

mybatis-plus超详细讲解

mybatis-plus (简化代码神器) 地址:https://mp.baomidou.com/ 目录 mybatis-plus 简介 特性 支持数据库 参与贡献 快速指南 1、创建数据库 mybatis_plus 2、导入相关的依赖 3、创建对应的文件夹 4、编写配置文件 5、编写代码 …...

【Linux】--- 进程的概念

【Linux】--- 进程的概念 一、进程概念二、PCB1.什么是PCB2.什么是task_struct(重点!)3.task_struct包含内容 三、task_struct内容详解1.查看进程(1)通过系统目录查看(2)通过ps命令查看&#xf…...

Unity NTPComponent应用, 实现一个无后端高效获取网络时间的组件

无后端高效获取网络时间的组件 废话不多说,直接上源码m_NowSerivceTime 一个基于你发行游戏地区的时间偏移, 比如北京时区就是 8, 巴西就是-3,美国就是-5using Newtonsoft.Json; 如果这里报错, 就说明项目没有 NewtonsoftJson插件…...

go语言使用zlib压缩[]byte

在Go语言中,可以使用compress/flate和compress/zlib包来实现对[]byte数据的Zlib压缩。下面是一个简单的示例,展示如何使用这些包来压缩一个字节切片: go package main import ( "bytes" "compress/zlib" "fmt"…...

Windows 配置 Tomcat环境

Windows配置Tomcat 1. 介绍 Tomcat是一个开源的、轻量级的Java应用服务器,在Java Web开发领域应用广泛。以下是关于它的详细介绍: 一、基本概念与背景 定义:Tomcat是Apache软件基金会(Apache Software Foundation)下…...

【python从入门到精通】-- 第六战:列表和元组

🌈 个人主页:白子寰 🔥 分类专栏:重生之我在学Linux,C打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您的订阅和支持~ 💡 坚持…...

Python | 数据可视化中常见的4种标注及示例

在Python的数据可视化中,标注(Annotation)技术是一种非常有用的工具,它可以帮助用户更准确地解释图表中的数据和模式。在本文中,将带您了解使用Python实现数据可视化时应该了解的4种标注。 常见的标注方式 文本标注箭…...

LearnOpenGL学习(高级OpenGL -> 高级GLSL,几何着色器,实例化)

完整代码见:zaizai77/Cherno-OpenGL: OpenGL 小白学习之路 高级GLSL 内建变量 顶点着色器 gl_PointSoze : float 输出变量,用于控制渲染 GL_POINTS 型图元时,点的大小。可用于粒子系统。将其设置为 gl_Position.z 时,可以使点…...

Scala学习记录

dao --------> 数据访问 mode ------> 模型 service ---->业务逻辑 Main -------> UI:用户直接操作,调用Service 改造UI层:...

vue使用pdfh5.js插件,显示pdf文件白屏

pdfh5,展示文件白屏,无报错 实现效果图解决方法(降版本)排查问题过程发现问题查找问题根源1、代码写错了?2、预览文件流的问题?3、pdfh5插件更新了,我的依赖包没更新?4、真相大白 彩蛋 实现效果图 解决方法…...

docker login 出错 Error response from daemon

在自己的Linux服务器尝试登陆docker出错 输入完用户密码之后错误如下: 解决方案 1.打开daemo文件: vim/etc/docker/daemon.json 2.常用的国内Docker 镜像源地址 网易云 Docker 镜像:http://hub-mirror.c.163.com 百度云 Docker 镜像&#x…...

Web 身份认证 --- Session和JWT Token

Web 身份认证 --- Session和JWT Token 方法一: 通过使用Session进行身份认证方法二: 通过JWT token进行身份认证什么是JWTJWT完整流程JWT攻防JWT 如何退出登录JWT的续签 方法一: 通过使用Session进行身份认证 用户第一次请求服务器的时候,服务器根据用户提交的相关信…...

UE5制作倒计时功能

设置画布和文本 文本绑定 格式化时间 转到事件图表,计算时间,时间结束后面的事件可以按自己需求写 进入关卡蓝图,添加倒计时UI...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...

写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里

写一个shell脚本&#xff0c;把局域网内&#xff0c;把能ping通的IP和不能ping通的IP分类&#xff0c;并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...

大模型真的像人一样“思考”和“理解”吗?​

Yann LeCun 新研究的核心探讨&#xff1a;大语言模型&#xff08;LLM&#xff09;的“理解”和“思考”方式与人类认知的根本差异。 核心问题&#xff1a;大模型真的像人一样“思考”和“理解”吗&#xff1f; 人类的思考方式&#xff1a; 你的大脑是个超级整理师。面对海量信…...

aurora与pcie的数据高速传输

设备&#xff1a;zynq7100&#xff1b; 开发环境&#xff1a;window&#xff1b; vivado版本&#xff1a;2021.1&#xff1b; 引言 之前在前面两章已经介绍了aurora读写DDR,xdma读写ddr实验。这次我们做一个大工程&#xff0c;pc通过pcie传输给fpga&#xff0c;fpga再通过aur…...