ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Sigma Web 开发课程实战:用 Express + Mongoose 构建 MongoDB 随机员工数据生成器

Sigma Web 开发课程实战:用 Express + Mongoose 构建 MongoDB 随机员工数据生成器 Sigma Web 开发课程实战用 Express Mongoose 构建 MongoDB 随机员工数据生成器【免费下载链接】Sigma-Web-Dev-CourseSource Code for Sigma Web Development Course项目地址: https://gitcode.com/GitHub_Trending/si/Sigma-Web-Dev-Course导读本篇文章基于 Sigma-Web-Dev-Course 仓库中 Video 99/question.md 的编程练习题目完整拆解一个按钮触发随机数据生成应用的实现在本地 MongoDB 的company数据库中维护一个员工employees集合每当用户点击页面上的生成按钮后端就清空旧数据、重新插入 10 条结构完全一致的随机员工记录。读完后你将掌握 Express 路由与 EJS 模板的配合方式、Mongoose 模型定义与create/deleteMany的核心用法、随机数据的生成技巧以及前后端通过fetch联动的完整闭环并顺带了解这套简单示例中值得注意的工程细节。仓库中 Video 99/main.js 提供了可运行的服务端实现Video 99/models/Employee.js 定义了数据模型Video 99/views/index.ejs 是带生成按钮的前端页面本文将结合这些源码逐层展开。一、题目需求拆解我们到底要做什么原始题目见 question.md提出了四条明确要求它们是整个实现的骨架定义数据结构在名为company的数据库中向employees集合写入形如下面的文档{ name: Harry, salary: 45000000, language: Python, city: New York, isManager: true }字段类型非常清晰name姓名字符串、salary薪资数字、language编程语言字符串、city城市字符串、isManager是否经理布尔值。一次生成 10 条每次触发都要插入 10 条这样的记录而不是 1 条。用 Express Mongoose 实现技术栈被限定为 ExpressWeb 框架与 MongooseMongoDB 的 ODM 层这要求我们同时具备写接口和操作数据库两种能力。按钮触发、先清后写页面必须有一个 generate data 按钮并且每一次点击都要先清空整个集合再重新生成保证数据量始终稳定在 10 条、不累积。仓库中的实现把第 4 条落地为一个独立的/generate路由其中await Employee.deleteMany({})负责清空随后循环Employee.create(...)10 次负责写入与题目要求一一对应。二、项目结构与环境准备Video 99 目录的组织方式非常清晰是 Express Mongoose 项目的典型布局Video 99/ ├── models/ │ └── Employee.js # Mongoose Schema 与模型 ├── views/ │ └── index.ejs # EJS 模板含生成按钮与 fetch 脚本 ├── main.js # Express 应用入口含 / 与 /generate 路由 ├── package.json # 依赖清单 └── question.md # 原始练习题目依赖声明位于 package.json共三个核心依赖express^4.18.2Web 框架负责路由与页面渲染mongoose^8.0.4MongoDB ODM负责连接数据库、定义模型与增删数据ejs^3.1.9模板引擎用于把服务端数据渲染成 HTML 页面。安装与启动流程如下本地需先运行 MongoDB 服务默认监听27017端口# 1. 安装依赖 npm install # 2. 启动应用 node main.js启动成功后访问http://localhost:3000即可看到带生成按钮的页面。三、定义数据模型Mongoose Schema 与 Employee 模型题目的数据结构被完整映射到了 Video 99/models/Employee.js 中全文只有 12 行却包含了 Mongoose 建模的全部关键步骤const mongoose require(mongoose); const employeeSchema new mongoose.Schema({ name: String, salary: Number, language: String, city: String, isManager: Boolean }); const Employee mongoose.model(Employee, employeeSchema); module.exports Employee这段代码值得逐点拆解Schema 字段类型声明String、Number、Boolean与题目要求的字段一一对应。Mongoose 的 Schema 类型既充当文档结构定义也是写入数据时的隐式校验器——例如把isManager传成字符串 true 时Mongoose 会尝试按Boolean类型做转换。模型名与集合名的关系mongoose.model(Employee, employeeSchema)注册了一个名为Employee的模型。Mongoose 默认会把模型名转为小写复数形式作为底层集合名因此Employee模型对应的集合恰好就是employees——这与题目要求在company数据库中写入employees集合完全吻合不需要额外指定第三个参数。模块化导出module.exports Employee使得模型可以在 main.js 中被require(./models/Employee)引用实现模型定义与业务逻辑的职责分离。四、数据库连接与 Express 应用骨架应用入口 main.js 的开头完成了三件事引入依赖、连接 MongoDB、配置 EJS 模板引擎。const express require(express) const app express() const mongoose require(mongoose); const Employee require(./models/Employee) conn mongoose.connect(mongodb://127.0.0.1:27017/company); const port 3000 app.set(view engine, ejs);其中两个细节是理解整个应用的关键连接串中的数据库名mongodb://127.0.0.1:27017/company末尾的company就是题目指定的数据库名。注意 MongoDB 采用惰性创建策略数据库和集合无需提前手工创建首次写入文档时才会真正落地。app.set(view engine, ejs)告诉 Express 使用 EJS 作为模板引擎。之后在路由里调用res.render(index, ...)时Express 会自动去views/目录查找index.ejs并渲染。仓库的 views/index.ejs 与这一默认查找规则对应。五、随机数据生成getRandom 工具函数在实现生成逻辑之前main.js 先定义了一个随机取值的辅助函数const getRandom (arr){ let rno Math.floor(Math.random() * (arr.length - 1)) return arr[rno] }它接收一个数组返回其中随机的一个元素。核心是Math.floor(Math.random() * (arr.length - 1))Math.random()产生[0, 1)的浮点数乘以(arr.length - 1)后向下取整得到一个从0到arr.length - 2的整数下标。这里有一个值得留意的边界细节由于乘数是arr.length - 1而不是arr.length数组的最后一个元素永远不会被取到。以randomNames [Rohan, Sohan, Mohan, Sobhan]为例下标只会落在 02 之间Sobhan永远缺席。从源码结构看这更像是写作者的一个无意疏漏更标准的写法是Math.floor(Math.random() * arr.length)可让下标覆盖 03 全部范围。读者在实际复刻时可以自行修正这一点。六、核心路由清空集合并批量生成 10 条数据题目的核心逻辑集中在/generate路由中见 main.jsapp.get(/generate, async (req, res) { // Clear the collection Employee await Employee.deleteMany({}) // Generate random data let randomNames [Rohan, Sohan, Mohan, Sobhan] let randomLang [Python, js, C, Java] let randomCities [Bilaspur, Moradabad, Mysore, Kolkata] for (let index 0; index 10; index) { let e await Employee.create({ name: getRandom(randomNames), salary: Math.floor(Math.random() * 22000), language: getRandom(randomLang), city: getRandom(randomCities), isManager: (Math.random()0.5)?true:false }) console.log(e) } res.render(index, { foo: FOO }); })这个路由与题目要求逐条对应同时也是 Mongoose 写操作的极佳示范await Employee.deleteMany({})清空集合。不传过滤条件{}表示删除集合中的所有文档直接落实题目每次点击按钮都先清空集合的约束。得益于 Mongoose 的 Promise 风格 API它配合async/await可以保证清空一定发生在生成之前。固定 10 次循环for (let index 0; index 10; index)与题目Generate 10 such records严格对应。Employee.create({...})插入单条文档。create 是 Mongoose 提供的便捷方法等价于new Employee(data).save()同时会执行 Schema 中的类型转换与校验。每次调用前都用await等待写入完成保证 10 条记录依次落库。三类随机策略name、language、city来自getRandom从候选数组中随机挑选注意上文提到的末尾元素不参与的问题salary用Math.floor(Math.random() * 22000)生成 021999 的随机整数isManager用Math.random() 0.5生成约 50% 概率的布尔值。console.log(e)每写入一条就把返回的文档打印到终端方便在服务端日志里直接确认生成结果。首页路由/则只是简单地渲染页面模板app.get(/, (req, res) { res.render(index, { foo: FOO }); })七、前端页面Bootstrap 按钮与 fetch 联动页面模板 views/index.ejs 借助 Bootstrap 5.3.2 的 CDN 搭好基础样式核心交互区域只有两个部分。按钮部分位于.container内div classcontainer button typebutton classbtn btn-successGenerate Now/button /div触发脚本页面底部的script标签内document.querySelector(.containerbutton).addEventListener(click, async (){ console.log(Yes) let a await fetch(/generate) let r await a.json() console.log(r) })这里体现了前后端联动的完整链路用户点击 Generate Now 按钮 → 前端向/generate发起fetch请求 → 后端执行清空 生成 10 条 → 响应返回前端。通过document.querySelector(.containerbutton)精确选中按钮并绑定click事件是 DOM 选择器在真实业务中的一个典型应用。不过这里有一个从源码结构可以明确看出的前后端契约不一致的问题前端期望a.json()即认为/generate会返回 JSON 数据但后端在 main.js 实际执行的是res.render(index, { foo: FOO })返回的是完整 HTML 页面。因此a.json()解析必然失败。这是初学者在页面刷新式与接口式两种后端响应模式之间切换时常犯的典型错误修正方式有两种后端改为返回 JSON把res.render(index, ...)替换为res.json({ success: true, count: 10 })与前端fetch().then(r r.json())匹配前端不再解析 JSON直接await fetch(/generate)后刷新页面或重新拉取数据把/generate当成动作型接口使用。题目本身只要求点击按钮生成数据两种修法都能满足理解这个不一致点比直接照抄代码更有价值。八、运行验证如何确认 10 条数据真的写入了完成npm install并启动 MongoDB 后按以下步骤验证整条链路启动服务node main.js看到Example app listening on port 3000即启动成功打开页面浏览器访问http://localhost:3000此时employees集合尚不存在或为空点击 Generate Now 按钮或直接在浏览器地址栏访问http://localhost:3000/generateGET 请求同样会触发验证数据有两种方式——观察服务端终端main.js中console.log(e)会打印 10 条完整文档使用mongosh或 MongoDB Compass 连接mongodb://127.0.0.1:27017/company执行db.employees.countDocuments()应返回10。再点击一次按钮后重新计数结果仍应为10而非20——这正是deleteMany({})先清后写所保证的行为也是检验题目第 4 条约束是否满足的直观方式。九、从练习题到工程实践可以继续深化的方向在完成题目要求的基础上这套最小示例还蕴含着多个值得深挖的进阶方向数据展示闭环当前页面只生成数据、不展示数据。可以让/generate生成后查询一次如Employee.find({})把结果传给 EJS 模板渲染成表格让生成→查看形成完整闭环Schema 校验增强在 Employee.js 中为字段补充required、min/max、enum等约束例如salary: { type: Number, min: 0 }把隐式类型转换升级为显式业务校验批量写入优化10 次Employee.create会触发 10 次数据库往返可改用Employee.insertMany(employeesArray)一次性写入体验 Mongoose 的批量写接口随机函数修正如第五节所述把getRandom的乘数改为arr.length或直接用arr[Math.floor(Math.random() * arr.length)]消除末位元素永不出现的边界问题环境配置化把 MongoDB 连接串与端口提取到.env或配置文件中避免硬编码为后续部署做准备。总结围绕 Video 99/question.md 的这道练习题我们完整走通了定义数据模型 → 连接数据库 → 实现清空与生成路由 → 前端按钮联动 → 运行验证的全流程。核心收获有三点Mongoose 中 Schema 类型与集合命名Employee→employees的映射规则、deleteMany与create组成的先清后写数据刷新模式、以及 Express EJS fetch 的前后端协作方式。同时main.js、models/Employee.js 与 views/index.ejs 三份源码也暴露了随机边界、JSON 契约等真实工程中会遇到的细节问题——带着这些认知去阅读和修改代码正是把这 10 条随机数据从练习题变成生产技能的关键一步。【免费下载链接】Sigma-Web-Dev-CourseSource Code for Sigma Web Development Course项目地址: https://gitcode.com/GitHub_Trending/si/Sigma-Web-Dev-Course创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进