新闻详情

新闻详情

首页 / 资讯中心 / 详情

Egg 项目接入 egg-mongoose:从 config.default.js 配置到常用 Mongoose 方法实战

发布时间:2026/9/30 12:40:53来源:尧图网络
Egg 项目接入 egg-mongoose:从 config.default.js 配置到常用 Mongoose 方法实战
1. Egg 项目里接 MongoDB为什么绕不开 egg-mongoose如果你正在用 Egg 写接口数据又要落到 MongoDB那 egg-mongoose 基本是默认选项。它把 Mongoose 的 Schema、Model、连接管理都挂到 Egg 的 app 和 ctx 上你不用在每个 Service 里手动 require mongoose也不用自己维护连接池。Egg 启动时会按 config 里的配置连库请求进来后直接this.ctx.model.Article就能用这对写业务代码的人来说省掉了很多样板。这篇面向的是已经有一个能跑起来的 Egg 项目、但还没接数据库或者接了但只会find一个方法的同学。我会从config.default.js的配置骨架开始把 model 目录约定、常用增删改查、聚合、分页排序都走一遍最后给一个能本地验证的请求示例。目标很明确照着做完你能在本地跑通一次完整的增删改查闭环而不是只停留在“装了个插件”。需要说明的是Mongoose 本身是操作 MongoDB 的 ODMegg-mongoose 是 Egg 生态里的封装插件。两者版本要匹配Egg 2.x 和 Egg 3.x 在插件加载方式上略有差异下面配置以 Egg 3.x 为主2.x 我会在排障部分点出来。2. 前置准备装插件、开插件、连上库2.1 安装 egg-mongoose在项目根目录执行npm install egg-mongoose --save如果你用的是 pnpm 或 yarn对应替换即可。装完后确认package.json的 dependencies 里有egg-mongoose版本号不用背能装上就说明源没问题。2.2 在 plugin.js 里启用插件Egg 的插件默认不生效必须在config/plugin.js里显式开启// config/plugin.js exports.mongoose { enable: true, package: egg-mongoose, };这一步很多人会漏结果启动时报ctx.model is undefined其实不是配置错是插件根本没加载。2.3 在 config.default.js 写连接配置连接信息放在config/config.default.js里推荐用环境变量兜底本地开发直接连本机// config/config.default.js module.exports appInfo { const config exports {}; config.mongoose { url: process.env.EGG_MONGODB_URL || mongodb://127.0.0.1:27017/website, options: { serverSelectionTimeoutMS: 5000, maxPoolSize: 40, }, }; return config; };这里有两个点值得说。第一url里带库名websiteMongoose 会自动切到这个库不用额外写dbName。第二maxPoolSize是连接池上限老版本 Mongoose 写的是poolSize新版本已经改成maxPoolSize如果你照旧教程写poolSize会看到弃用警告功能还能用但不建议。注意本地 MongoDB 默认端口是 27017如果你用 Docker 起库记得把端口映射出来否则连接会超时。2.4 model 目录约定Egg 约定 model 放在app/model/下文件名就是 model 名的小写。比如app/model/article.js对应app.model.Article。这个约定不能改改了加载不到。// app/model/article.js use strict; module.exports app { const mongoose app.mongoose; const Schema mongoose.Schema; const ArticleSchema new Schema({ title: { type: String, required: true }, keywords: { type: String }, sort: { type: Number, default: 0 }, isSetTop: { type: Number, default: 0 }, release: { type: Boolean, default: false }, columnId: { type: Schema.Types.ObjectId }, tags: { type: Array }, updateTime: { type: Date, default: Date.now }, }); return mongoose.model(Article, ArticleSchema); };Schema 里type支持 String、Number、Boolean、Date、ObjectId、Array、Object 等。ObjectId常用于关联其他集合的_idArray适合标签这类多值字段。default和required是常用约束能省掉不少业务层校验。3. 可复制配置Service 里怎么写增删改查Egg 里操作数据库一般放在 ServiceController 只做参数校验和响应。下面按 create、find、updateOne、aggregate 四类给示例。3.1 新增create// app/service/article.js const Service require(egg).Service; class ArticleService extends Service { async createArticle(payload) { const { ctx } this; const result await ctx.model.Article.create({ title: payload.title, keywords: payload.keywords, sort: payload.sort || 0, tags: payload.tags || [], }); return result; } } module.exports ArticleService;create返回的是插入后的文档对象里面带_id。如果你传的是数组它会批量插入并返回数组。3.2 查询find 与条件查询async listArticles(query) { const { ctx } this; const conditions {}; if (query.title) { conditions.title new RegExp(query.title, i); } if (query.minSort ! undefined) { conditions.sort { $gte: Number(query.minSort) }; } return ctx.model.Article.find(conditions) .sort({ isSetTop: -1, sort: 1, updateTime: -1 }) .skip(Number(query.pageSize) * (Number(query.pageNum) - 1)) .limit(Number(query.pageSize)) .lean(); }这里用了几个常用操作符$gte大于等于$lt小于$ne不等于$in匹配多个值$exists判断字段是否存在。正则用new RegExp比字面量更灵活能动态拼关键词。.lean()返回纯 JS 对象而不是 Mongoose Document读多写少的列表接口用它性能更好。3.3 更新updateOne 与更新修改器async updateArticle(id, payload) { const { ctx } this; return ctx.model.Article.updateOne( { _id: id }, { $set: { title: payload.title, updateTime: new Date() }, $inc: { sort: 1 }, } ); }updateOne返回{ acknowledged, modifiedCount, matchedCount }modifiedCount为 0 说明条件没匹配到或者值没变化。常用修改器有$set设置值、$inc自增、$unset删字段、$push往数组加元素、$pull从数组删元素、$addToSet去重添加。数组批量插入可以配合$each。3.4 聚合aggregate统计每个栏目的文章数async countByColumn() { const { ctx } this; return ctx.model.Article.aggregate([ { $match: { release: true } }, { $group: { _id: $columnId, total: { $sum: 1 } } }, { $sort: { total: -1 } }, ]); }aggregate返回的是普通数组不走 Mongoose 的 Document 包装。$match相当于 where$group做分组$sum累加。聚合管道写起来像流水线每一步的输出是下一步的输入复杂统计基本都能拼出来。4. 验证请求本地跑通一次闭环配置和 Service 写完后加一个 Controller 和路由用 curl 验证。// app/controller/article.js const Controller require(egg).Controller; class ArticleController extends Controller { async create() { const { ctx } this; const body ctx.request.body; const result await ctx.service.article.createArticle(body); ctx.body { code: 0, data: result }; } async list() { const { ctx } this; const list await ctx.service.article.listArticles(ctx.query); ctx.body { code: 0, data: list }; } } module.exports ArticleController;// app/router.js module.exports app { const { router, controller } app; router.post(/api/article, controller.article.create); router.get(/api/article, controller.article.list); };启动项目npm run dev先插一条curl -X POST http://127.0.0.1:7001/api/article \ -H Content-Type: application/json \ -d {title:Egg接入Mongoose,keywords:egg,mongoose,sort:10,tags:[node,egg]}返回里应该能看到_id和title。再查列表curl http://127.0.0.1:7001/api/article?pageNum1pageSize5minSort5如果返回数组里有刚才那条说明连接、model、Service、路由整条链路都通了。这一步别跳过很多人配置写完不验证等到业务报错才回头查成本更高。5. 本篇常见错排查报错ctx.model is undefined九成是config/plugin.js没开插件或者 model 文件没放在app/model/下。Egg 是按目录约定加载的路径错了不会报文件不存在只会静默不注册。连接超时MongooseServerSelectionError先确认 MongoDB 进程在跑mongosh能连上再确认url里的 host 和端口对。Docker 场景常见的是容器内用了127.0.0.1应该换成容器名或宿主机 IP。poolSize弃用警告Mongoose 6 以后连接池参数改成maxPoolSize把options.server.poolSize换成顶层maxPoolSize即可。updateOne返回modifiedCount: 0要么条件没匹配到要么新值和旧值一样。可以先用findOne确认数据存在再检查$set的字段是否真的变了。Egg 2.x 与 3.x 差异2.x 的插件配置和 model 加载基本一致但部分中间件和appInfo用法不同。如果你从 2.x 升级重点看config.default.js的导出方式3.x 推荐module.exports appInfo {}。聚合结果为空$match里的字段名要带$前缀引用文档字段比如$columnId写成columnId会被当成字符串常量结果自然不对。6. 把模型调用接到稳定的 API 通道上本地跑通之后下一步通常是把这些 model 调用接到真实的模型服务或业务接口上。这时候请求的稳定性和 Key 管理就变得重要。我一般会把模型调用统一走 TaoToken 的 API 通道地址是 https://taotoken.net/api Key 在控制台生成接入文档里有各语言的示例照着改 base_url 就行。如果你只是先验证模型返回可以直接用模型对话页面试一条请求确认通道通了再写进代码。长期做编码或 Agent 类项目的话Coding Plan 更适合额度和调用方式都按开发场景设计。控制台里可以管理 API Keys接入文档在 https://taotoken.net/doc ClaudeCodeAnthropic 相关的配置也有单独说明。把这些前置动作做完再回到 Egg 的 Service 里发请求排障时就能分清是数据库层的问题还是模型通道的问题定位会快很多。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

浏览器端(Client-Side)安全审计实战指南:DOM XSS、跨源消息与 Service Worker 攻击面的猎杀与验证规范 2026/9/30 14:38:14

浏览器端(Client-Side)安全审计实战指南:DOM XSS、跨源消息与 Service Worker 攻击面的猎杀与验证规范

AI 技能应用安全 【免费下载链接】security-audit-skill A coding-agent skill for multi-phase security audits with independently verified, machine-readable findings 项目地址: https://gitcode.com/GitHub_Trending/se/security-audit-skill 点击查看 免费下…

阅读更多 →
技术跃升、权力野心与治理真空:从两次世界大战到人工智能时代的结构性风险 2026/9/30 14:38:14

技术跃升、权力野心与治理真空:从两次世界大战到人工智能时代的结构性风险

技术跃升、权力野心与治理真空:从两次世界大战到人工智能时代的结构性风险摘要 本文从技术与治理的时间不对称出发,重新审视第一次世界大战与第二次世界大战的深层根源,并以此为历史参照,分析当代人工智能(AI&#xff…

阅读更多 →
私域商城搭建从零开始,第一批客户从哪来 2026/9/30 14:38:14

私域商城搭建从零开始,第一批客户从哪来

2026年,AI应用类小程序数量半年增长近40%,各类建站工具把开店的门槛压到了最低,几千元预算、几天时间就能上线一个私域商城。但很多创业者的真实处境是:商城搭好了,页面也装修了,就是没人进来。私域商城搭建…

阅读更多 →
深度学习入门指南:从核心概念到 PyTorch 实战 2026/9/30 14:38:14

深度学习入门指南:从核心概念到 PyTorch 实战

从线性回归到 KNN,从决策树到聚类,我们一路走过了机器学习的主要算法。但这些算法都有一个共同的特点——它们处理的是"浅层"特征,需要人工提取和选择特征。而深度学习的革命性在于:它能自动从原始数据中提取特征&#…

阅读更多 →
企业上网行为监控软件怎么选?避开这8个坑,再看如何满足要求 2026/9/30 14:38:07

企业上网行为监控软件怎么选?避开这8个坑,再看如何满足要求

免责声明:本文仅讨论企业合法合规管理场景。部署上网行为监控前,请务必咨询法务,完善员工手册、IT制度,履行告知义务,坚持“工作必需、最小必要、目的限定”原则。不要监控员工私人设备、私人账号和非工作场景。很多IT…

阅读更多 →
2026 Turnitin 查重和 AI 检测都不过?一站式降AI率网站实测解析 2026/9/30 14:38:06

2026 Turnitin 查重和 AI 检测都不过?一站式降AI率网站实测解析

一、前言:2026 高校论文审核新难题 随着高校学术审核体系不断升级,知网、维普等主流检测平台全面上线AIGC 智能检测功能,当代毕业生的论文写作与修改迎来双重考验。以往论文仅需攻克重复率超标问题,如今还要规避 AI 写作痕迹检测风…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉