首页/新闻资讯/正文详情

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

发布时间:2026/9/27 11:39:00 来源:云帆数科 栏目:资讯中心
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 里发请求排障时就能分清是数据库层的问题还是模型通道的问题定位会快很多。

相关推荐

OpenClaw 理性评估:国内开发者如何用 TaoToken 统一 Key 接入 AI 代理
OpenClaw 理性评估:国内开发者如何用 TaoToken 统一 Key 接入 AI 代理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 11:38:54

备战2026金九银十:用TaoToken统一Key一周打通AI前端TypeScript+SSE+RAG+MCP实战大纲
备战2026金九银十:用TaoToken统一Key一周打通AI前端TypeScript+SSE+RAG+MCP实战大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 11:38:54

微软 Azure DevOps Skills 实战:用 SKILL.md 让 AI 助手接管 DevOps 工作流
微软 Azure DevOps Skills 实战:用 SKILL.md 让 AI 助手接管 DevOps 工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 11:38:54

ASP做网站安全性图解步骤:3个漏洞堵住流量断崖
ASP做网站安全性图解步骤:3个漏洞堵住流量断崖

ASP做网站安全性图解步骤:3个漏洞堵住流量断崖 网站做好了没人访问,这不仅是流量焦虑,更是技术硬伤的直接体现。很多站长盯着后台数据发愁,以为只是SEO没做好,其实根源往往藏在代码底层。ASP作为老牌技术,若忽视 asp做网站安全性… · 2026/9/27 12:18:52

做网站开发的经营范围避坑指南:别让执照卡住流量
做网站开发的经营范围避坑指南:别让执照卡住流量

做网站开发的经营范围避坑指南:别让执照卡住流量 网站做好了没人访问,这比没做还让人心慌。你盯着后台数据,点击量寥寥无几,心里直打鼓:钱花了,时间搭进去了,怎么连个水花都没有?这时候很多老板才想起来,自己公司注册时填的“经营范围”里,压根没写… · 2026/9/27 12:18:46

织梦cms网站没流量?3步优化法教你选对SEO哪家好
织梦cms网站没流量?3步优化法教你选对SEO哪家好

织梦cms网站没流量?3步优化法教你选对SEO哪家好 网站做好了没人访问,是不是心塞?别急着怪百度,90%的织梦CMS网站死在“伪静态没配好”和“TDK标签乱填”上。很多老板问SEO哪家好,其实不是选公司,是看谁懂织梦的底层逻辑。今天不扯虚… · 2026/9/27 12:18:34

网站建设的总体目标包含哪几个方面注意事项
网站建设的总体目标包含哪几个方面注意事项

网站建设总体目标包含哪几个方面速查手册救活死站 网站做好了没人访问,这行干了十年,见过太多老板砸几十万做出来的站,上线三个月UV(独立访客)还没破百。别急着怪百度不给你流量,多半是你在建设初期就定错了方向。很多人以为网站建设就是找个模板套上… · 2026/9/27 12:18:22

莱芜车管所网站哪家好?3个避坑点+1套方案,省下50%预算
莱芜车管所网站哪家好?3个避坑点+1套方案,省下50%预算

莱芜车管所网站哪家好?3个避坑点+1套方案,省下50%预算 找建站公司最怕什么?不是技术烂,而是被坑高价。很多业务负责人在咨询莱芜车管所网站哪家好时,心里没底:报价单上列着几千块的模板,转头又说需要定制,最后费用翻了三倍。别急,咱们不玩虚的… · 2026/9/27 12:17:57

3招搞懂百度推广渠道怎么选,别再把钱打水漂
3招搞懂百度推广渠道怎么选,别再把钱打水漂

3招搞懂百度推广渠道怎么选,别再把钱打水漂 网站做好了没人访问,这是很多老板最头疼的事。你花了几万块做了个高大上的官网,结果打开一看,后台流量全是零。这时候有人跳出来告诉你,得投百度推广。但百度推广渠道到底怎么选?是选信息流、搜索竞价,还是… · 2026/9/27 12:17:45

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码