第六课:数据库集成:MongoDB与Mongoose技术应用

news2025/3/12 12:05:02

本文详细介绍了如何在Node.js应用程序中集成MongoDB数据库,并使用Mongoose库进行数据操作。我们将涵盖MongoDB在Ubuntu 20系统中的安装、Bash命令的CRUD操作、Mongoose数据建模(Schema/Model)、关联查询与聚合管道,以及实战案例——用户注册系统的开发。通过本文,你将掌握Node.js与MongoDB集成的完整流程。

1. MongoDB在Ubuntu 20系统中安装与Bash命令的CRUD操作

1.1 MongoDB安装

在Ubuntu 20系统中安装MongoDB,你可以通过以下步骤进行:

方法一:直接安装

导入公共GPG密钥

wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add -

创建MongoDB源列表文件

echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

更新软件包列表并安装MongoDB

sudo apt-get update

sudo apt-get install -y mongodb-org

启动MongoDB服务

sudo systemctl start mongod

sudo systemctl enable mongod

方法二:使用Docker镜像

如果你更喜欢使用Docker来管理MongoDB,可以使用以下命令:

docker pull mongo

docker run -itd --name mongo_latest -p 27017:27017 mongo

然后,你可以通过docker exec -it mongo_latest mongosh进入MongoDB shell

1.2 Bash命令的CRUD操作

增操作

mongo

use myDatabase

db.users.insert({name: "deming_su", age: 22, email: "deming_su@163.com"})

查操作

db.users.find()

更操作

db.users.updateOne({name: "deming_su"}, {$set: {age: 23}})

删操作

db.users.deleteOne({name: "deming_su"})

2. Mongoose数据建模(Schema/Model)

2.1 Mongoose安装

首先,确保你的Node.js环境已经安装完毕,然后通过npm安装Mongoose:

npm install mongoose

2.2 定义Schema

Schema是Mongoose中用于定义文档结构的蓝图。以下是一个简单的用户Schema示例:

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    id: String,
    name: String,
    age: Number,
    email: {
        type: String,
        unique: true
    }
});
2.3 创建Model

Model是Schema的编译版本,用于创建和操作数据库中的文档。你可以使用mongoose.model方法创建Model:

const User = mongoose.model('User', userSchema);
2.4 CRUD操作

使用Mongoose进行CRUD操作非常简单。以下是一些示例:

增操作

const mongoose = require('mongoose');
const User = require('./models/user');

mongoose.connect('mongodb://localhost:27017/myDatabase', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

const newUser = new User({id: "deming_su", name: "deming_su", age: 28, email: "deming_su@163.com"});

newUser.save();

查操作

User.find({id: "deming_su"}, (err, users) => {
    if (err) {
        console.error(err);
    } else {
        console.log(users);
    }
});

更操作

User.findByIdAndUpdate('deming_su', {$set: {age: 29}}, (err, user) => {
    if (err) {
        console.error(err);
    } else {
        console.log(user);
    }
});

删操作

User.findByIdAndDelete('deming_su', (err, user) => {
    if (err) {
        console.error(err);
    } else {
        console.log(user);
    }
});

3. 关联查询与聚合管道

3.1 关联查询

在MongoDB中,关联查询通常通过$lookup操作符在聚合管道中实现。假设我们有两个集合:users和orders,每个订单都属于一个用户,我们可以通过user_id字段进行关联查询。

User.aggregate([
    {
        $lookup: {
            from: 'orders',
            localField: '_id',
            foreignField: 'user_id',
            as: 'orders'
        }
    }
]).exec((err, users) => {
    if (err) {
        console.error(err);
    } else {
        console.log(users);
    }
});
3.2 聚合管道

聚合管道允许你对集合中的文档进行一系列复杂的转换和聚合操作。以下是一个简单的聚合管道示例,用于统计每个用户的订单总数:

Order.aggregate([
    {
        $group: {
            _id: '$user_id',
            totalOrders: { $sum: 1 }
        }
    }
]).exec((err, results) => {
    if (err) {
        console.error(err);
    } else {
        console.log(results);
    }
});

4. 实战:用户注册系统开发

4.1 系统设计

用户注册系统需要实现以下功能:

  • 用户注册:收集用户信息(如用户名、密码、邮箱等)并保存到数据库。
  • 用户登录:验证用户信息并登录系统。
  • 用户注销:清除用户会话并注销系统。
4.2 数据建模

首先,我们需要定义用户数据模型。使用Mongoose,我们可以创建一个简单的用户Schema:

const mongoose = require('mongoose');
 
const userSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true,
        unique: true
    }
});
4.3 实现注册功能

前端(HTML + JavaScript)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>User Registration</title>
</head>
<body>
    <form id="registerForm">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required><br><br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required><br><br>
        <label for="email">Email:</label>
        <input type="email" id="email" name="email" required><br><br>
        <button type="submit">Register</button>
    </form>
 
    <script>
        document.getElementById('registerForm').addEventListener('submit', async function(event) {
            event.preventDefault();
            const username = document.getElementById('username').value;
            const password = document.getElementById('password').value;
            const email = document.getElementById('email').value;
 
            const response = await fetch('/register', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ username, password, email })
            });
 
            const result = await response.json();
            if (result.success) {
                alert('Registration successful!');
            } else {
                alert('Registration failed: ' + result.message);
            }
        });
    </script>
</body>
</html>

后端(Node.js + Express + Mongoose)

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
 
const app = express();
const port = 3000;
 
mongoose.connect('mongodb://localhost:27017/userRegistration', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});
 
app.use(bodyParser.json());
 
const User = require('./models/user');
 
app.post('/register', async (req, res) => {
    const { username, password, email } = req.body;
 
    try {
        const user = new User({ username, password, email });
        await user.save();
        res.json({ success: true });
    } catch (err) {
        res.json({ success: false, message: err.message });
    }
});
 
app.listen(port, () => {
    console.log(`Server is running on http://localhost:${port}`);
});
4.4 实现登录和注销功能

登录和注销功能的实现与注册类似,这里不再赘述。你可以参考上述代码,通过发送POST请求到/login和/logout端点来实现用户登录和注销功能。

结语

通过本文,你了解了如何在Node.js应用程序中集成MongoDB数据库,并使用Mongoose库进行数据操作。我们涵盖了MongoDB的安装、Bash命令的CRUD操作、Mongoose数据建模、关联查询与聚合管道,以及实战案例——用户注册系统的开发。希望这些内容对你有所帮助,让你能够更好地掌握Node.js与MongoDB的集成技术。

关注我!!🫵 持续为你带来Nodejs相关内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2311565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TypeError: Cannot set properties of undefined (setting ‘xxx‘)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

windows下使用msys2编译ffmpeg

三种方法&#xff1a; 1、在msys2中使用gcc编译 2、在msys2中使用visual studio编译&#xff08;有环境变量&#xff09; 3、在msys2中使用visual studio编译&#xff08;无环境变量&#xff09; 我的环境&#xff1a; 1、msys2-x86_64-20250221 2、vs2015 3、ffmpeg-7.1…

可视化+图解链表

链表&#xff08;Linked list&#xff09;是一种常用的数据结构&#xff0c;它由一系列节点组成&#xff0c;每个节点包含数据域和指针域。指针域存储了下一个节点的地址&#xff0c;从而建立起各节点之间的线性关系。 1、链表节点 1.1 节点构成 链表节点如下图所示&#xff…

Docker参数,以及仓库搭建

一。Docker的构建参数 注释&#xff1a; 1.对于CMD&#xff0c;如果不想显示&#xff0c;而是使用交互界面&#xff1a;docker run -ti --rm --name test2 busybox:v5 sh 2.对于CMD&#xff0c;一个交互界面只可以使用一个&#xff0c;如果想多次使用CMD&#xff0c;则用ENTR…

正十七边形尺规作图证明——从高斯的发现到几何实现

正十七边形尺规作图证明——从高斯的发现到几何实现 1. 引言&#xff1a;一个历史性的数学突破 在欧几里得几何中&#xff0c;尺规作图&#xff08;仅使用直尺和圆规&#xff09;是最为基础的几何构造方法。古希腊数学家已知如何构造正三角形、正方形和正五边形&#xff0c;但…

常见Web应用源码泄露问题

文章目录 前言一、常见的源码泄露漏洞git源码泄露SVN源码泄露DS_Store文件泄漏网站备份压缩文件泄露WEB-INF/web.xml泄露CVS泄露.hg源码泄露Bazaar/bzr泄露.swp文件泄露 前言 在Web应用方面对于安全来说&#xff0c;可能大家对SQL注入、XSS跨站脚本攻击、文件上传等一些漏洞已…

使用Modelsim手动仿真

FPGA设计流程 在设计输入之后,设计综合前进行 RTL 级仿真,称为综合前仿真,也称为前仿真或 功能仿真。前仿真也就是纯粹的功能仿真,主旨在于验证电路的功能是否符合设计要求,其特点是不考虑电路门延迟与线延迟。在完成一个设计的代码编写工作之后,可以直接对代码进行仿真,…

利用 ArcGIS Pro 快速统计省域各市道路长度的实操指南

在地理信息分析与处理的工作中&#xff0c;ArcGIS Pro 是一款功能强大的 GIS 软件&#xff0c;它能够帮助我们高效地完成各种复杂的空间数据分析任务。 现在&#xff0c;就让我们一起深入学习如何借助 ArcGIS Pro 来统计省下面各市的道路长度&#xff0c;这一技能在城市规划、…

1.4 单元测试与热部署

本次实战实现Spring Boot的单元测试与热部署功能。单元测试方面&#xff0c;通过JUnit和Mockito等工具&#xff0c;结合SpringBootTest注解&#xff0c;可以模拟真实环境对应用组件进行独立测试&#xff0c;验证逻辑正确性&#xff0c;提升代码质量。具体演示了HelloWorld01和H…

掌握Kubernetes Network Policy,构建安全的容器网络

在 Kubernetes 集群中&#xff0c;默认情况下&#xff0c;所有 Pod 之间都是可以相互通信的&#xff0c;这在某些场景下可能会带来安全隐患。为了实现更精细的网络访问控制&#xff0c;Kubernetes 提供了 Network Policy 机制。Network Policy 允许我们定义一组规则&#xff0c…

结合rpart包的决策树介绍

决策树与CART算法 决策树是一种基于树状结构的监督学习算法。它通过从根节点开始递归地对特征进行划分&#xff0c;构建出一棵树来进行决策。决策树的构建过程需要解决的重要问题有三个&#xff1a;如何选择自变量、如何选择分割点、确定停止划分的条件。解决这些问题是希望随…

VScode代码格式化插件black失效问题

之前有如下提示&#xff1a; 没太当回事&#xff0c;发现还能用。之后突然就用不了了&#xff0c;跟着官方插件的文档来查看log&#xff1a; 查看发现提示&#xff1a; Message: TypeError: type object is not subscriptable 在github界面找到解决方案&#xff1a;安装Versio…

【经验分享】Ubuntu20.04编译RK3568 AI模型报错问题(已解决)

【经验分享】Ubuntu20.04编译RK3568 AI模型报错问题&#xff08;已解决&#xff09; 前言问题现象问题分析解决方案总结 前言 这里使用的是Rockchip提供的rknn_model_zoo&#xff0c;https://github.com/airockchip/rknn_model_zoo/tree/main 此解决方案适用于Rockchip芯片在U…

AI革命先锋:DeepSeek与蓝耘通义万相2.1的无缝融合引领行业智能化变革

云边有个稻草人-CSDN博客 目录 引言 一、什么是DeepSeek&#xff1f; 1.1 DeepSeek平台概述 1.2 DeepSeek的核心功能与技术 二、蓝耘通义万相2.1概述 2.1 蓝耘科技简介 2.2 蓝耘通义万相2.1的功能与优势 1. 全链条智能化解决方案 2. 强大的数据处理能力 3. 高效的模型…

基于SpringBoot实现旅游酒店平台功能一

一、前言介绍&#xff1a; 1.1 项目摘要 随着社会的快速发展和人民生活水平的不断提高&#xff0c;旅游已经成为人们休闲娱乐的重要方式之一。人们越来越注重生活的品质和精神文化的追求&#xff0c;旅游需求呈现出爆发式增长。这种增长不仅体现在旅游人数的增加上&#xff0…

轻松上手 —— 通过 RPM 包快速部署 NebulaGraph

前言 在当今大数据时代&#xff0c;处理复杂关系数据的需求与日俱增&#xff0c;图数据库应运而生并逐渐崭露头角。NebulaGraph 作为一款高性能、分布式且易扩展的图数据库&#xff0c;专为应对大规模图数据处理而精心打造。它不仅具备丰富的查询语言&#xff0c;还拥有强大高效…

MetaGPT发布的MGX与Devin深度对比

家人们&#xff0c;搞编程的都知道&#xff0c;工具选对了&#xff0c;效率能翻倍&#xff01;今天必须给大伙唠唠MetaGPT发布的MGX编程助手和Devin编程助手 。 先看MGX&#xff0c;简直是编程界的王炸&#xff01;它就像一个超神的虚拟开发团队&#xff0c;一堆智能助手分工明…

03.06 QT

一、使用QSlider设计一个进度条&#xff0c;并让其通过线程自己动起来 程序代码&#xff1a; <1> Widget.h: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QThread> #include "mythread.h"QT_BEGIN_NAMESPACE namespace Ui {…

SpringUI:打造高质量Web交互设计的首选元件库

SpringUI作为一个专为Web设计与开发领域打造的高质量交互元件库&#xff0c;确实为设计师和开发者提供了极大的便利。以下是对SpringUI及其提供的各类元件的详细解读和一些建议&#xff1a; SpringUI概述 SpringUI集合了一系列预制的、高质量的交互组件&#xff0c;旨在帮助设…

鸿蒙Android4个脚有脚线

效果 min:number122max:number150Row(){Stack(){// 底Text().border({width:2,color:$r(app.color.yellow)}).height(this.max).aspectRatio(1)// 长Text().backgroundColor($r(app.color.white)).height(this.max).width(this.min)// 宽Text().backgroundColor($r(app.color.w…