ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

Mongoose 安装与增删改查:TaoToken 统一 Key 接入 Node.js 项目配置骨架

Mongoose 安装与增删改查:TaoToken 统一 Key 接入 Node.js 项目配置骨架 1. 从一次本地数据层踩坑说起Mongoose 到底解决什么问题如果你正在写 Node.js 项目迟早会遇到一个绕不开的问题数据怎么存、怎么查、怎么改。直接拿 MongoDB 原生驱动写语法松散、字段没约束、回调嵌套深项目一大就乱。Mongoose 就是来解决这件事的——它是 MongoDB 的 ODM对象文档映射库用 Schema 给集合定规矩用 Model 封装增删改查让 Node.js 里的数据层像写对象一样自然。这篇聚焦的是「Mongoose 安装与增删改查」的完整落地路径适合刚接触 Node.js 后端、想把本地数据层跑通的同学。我会从 npm 安装讲到 Schema 建模再到 create/find/update/delete 四类操作同时把 TaoToken 统一 Key 接入的环境变量与 config 骨架一起配好这样你后面接模型能力时不用再返工。整个过程在本地就能验证不需要复杂环境。我试过最省事的做法先建一个干净目录把 package.json 和配置骨架一次性写对再装依赖。这样能避开后面要讲的 EJSONPARSE 报错。下面按步骤来每段都能直接复制。2. TaoToken 前置统一 Key 与项目配置骨架在写 Mongoose 代码之前先把项目的「外部通道」配置好。TaoToken 提供统一的 API 通道官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。它的作用是让你用一个 Key 就能对接多种模型能力不用为每个服务单独维护密钥。你需要先去控制台创建一个 API Key入口在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 的创建和管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。拿到 Key 之后不要硬编码进代码而是放进环境变量这是后面 config 骨架的核心。项目根目录建一个.env文件记得加进 .gitignore# .env TAOTOKEN_API_KEYsk-你的实际key TAOTOKEN_BASE_URLhttps://taotoken.net/api MONGO_URImongodb://127.0.0.1:27017/mongoose_test如果你更习惯用 JSON 或 TOML 管理配置下面两个片段可以直接用。settings.json 适合 VS Code 或某些工具链读取{ taotoken: { baseUrl: https://taotoken.net/api, apiKeyEnv: TAOTOKEN_API_KEY }, mongo: { uri: mongodb://127.0.0.1:27017/mongoose_test } }config.toml 适合 Python 风格或需要强类型配置的场景[taotoken] base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY [mongo] uri mongodb://127.0.0.1:27017/mongoose_test注意配置文件里只放「环境变量名」不放 Key 明文。这样即使配置进了版本库也不会泄露。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 遇到参数问题可以对照查。3. 可复制配置Mongoose 安装与连接骨架3.1 初始化项目并安装 Mongoose先建目录、初始化 package.json再装依赖。这一步顺序很重要很多人跳过初始化直接npm install mongoose结果报 EJSONPARSE。mkdir mongoose-crud cd mongoose-crud npm init -y npm install mongoose dotenvnpm init -y会生成一个合法的 package.json。如果你手动创建了 package.json 但内容为空或只有注释npm 解析时会报Unexpected end of JSON input。解决办法就是保证 package.json 是合法 JSON至少包含 name 和 version{ name: mongoose-crud, version: 1.0.0, main: index.js, type: commonjs }装完后确认版本npm ls mongoose3.2 连接 MongoDB 与状态监听新建db.js把连接逻辑单独抽出来方便复用// db.js require(dotenv).config(); const mongoose require(mongoose); const MONGO_URI process.env.MONGO_URI || mongodb://127.0.0.1:27017/mongoose_test; async function connectDB() { await mongoose.connect(MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true, }); } mongoose.connection.once(open, () { console.log(数据库连接成功); }); mongoose.connection.once(close, () { console.log(数据库连接已经断开); }); module.exports { connectDB, mongoose };这里两个参数useNewUrlParser和useUnifiedTopology是为了消除旧版驱动的 DeprecationWarning。虽然新版 Mongoose 已经默认启用但显式写上兼容性更好也避免你看到一堆黄色警告心里发慌。3.3 Schema 与 Model 骨架新建models/student.js把 Schema 和 Model 定义清楚// models/student.js const mongoose require(mongoose); const Schema mongoose.Schema; const stuSchema new Schema({ name: { type: String, required: true }, age: Number, gender: { type: String, default: female }, address: String, }); const StuModel mongoose.model(student, stuSchema); module.exports StuModel;mongoose.model(student, stuSchema)里的 student 会被自动映射成集合名students复数。这是 Mongoose 的默认行为别被数据库里看到的复数名搞懵。4. 验证请求CRUD 冒烟测试与成功结果4.1 插入数据新建crud.js先跑插入// crud.js const { connectDB, mongoose } require(./db); const StuModel require(./models/student); async function run() { await connectDB(); const created await StuModel.create({ name: 沙和尚, age: 38, gender: male, address: 流沙河, }); console.log(插入成功:, created._id); await mongoose.connection.close(); } run().catch((err) console.error(err));执行node crud.js终端输出「数据库连接成功」和「插入成功: 一串ObjectId」说明写入链路通了。4.2 查询数据把 run 函数改成查询验证读取async function run() { await connectDB(); // 查所有 const all await StuModel.find({}); console.log(全部文档:, all); // 条件查询 投影只要 name 和 age不要 _id const some await StuModel.find({ gender: male }, name age -_id); console.log(男性文档:, some); // 分页跳过 1 条取 2 条 const paged await StuModel.find({}, name -_id, { skip: 1, limit: 2 }); console.log(分页结果:, paged); // 按 id 查单条 const one await StuModel.findById(all[0]._id); console.log(按 id 查:, one.name); await mongoose.connection.close(); }投影有两种写法对象形式{ name: 1, _id: 0 }和字符串形式name -_id。1 表示返回0 表示不返回字符串里带-表示排除。两种效果一样选你顺手的。4.3 修改数据async function run() { await connectDB(); const res await StuModel.updateOne( { name: 沙和尚 }, { $set: { age: 40 } } ); console.log(匹配数:, res.matchedCount, 修改数:, res.modifiedCount); const updated await StuModel.findOne({ name: 沙和尚 }); console.log(修改后年龄:, updated.age); await mongoose.connection.close(); }updateOne返回的对象里有matchedCount和modifiedCount能清楚知道有没有真的改到。如果匹配数为 0说明条件写错了别急着怀疑数据库。4.4 删除与计数async function run() { await connectDB(); const del await StuModel.deleteOne({ name: 沙和尚 }); console.log(删除数:, del.deletedCount); const count await StuModel.countDocuments({}); console.log(剩余文档数:, count); await mongoose.connection.close(); }注意旧版教程里的Model.remove()和Model.count()在新版 Mongoose 中已废弃分别用deleteOne/deleteMany和countDocuments替代。如果你照抄老代码看到废弃警告换成新 API 即可。5. 本篇常见错排查5.1 EJSONPARSEpackage.json 不是合法 JSON报错长这样npm ERR! code EJSONPARSE npm ERR! JSON.parse Failed to parse json npm ERR! JSON.parse Unexpected end of JSON input while parsing near 原因就是 package.json 为空、只有注释、或末尾多了逗号。解决确保它是合法 JSON至少{ name: mongoose-crud }。改完重新npm install mongoose。5.2 DeprecationWarningServer Discovery 引擎废弃DeprecationWarning: current Server Discovery and Monitoring engine is deprecated在mongoose.connect的第二个参数里加{ useNewUrlParser: true, useUnifiedTopology: true }。新版 Mongoose 可能不再提示但写上无害。5.3 连接成功但查不到数据先确认集合名。mongoose.model(student, schema)映射的是students集合。如果你在 MongoDB 里手动建了student集合两边对不上。用show collections看一眼实际集合名。5.4 回调不执行老式回调写法StuModel.find({}, function(err, docs){})里如果回调没传查询压根不会发起。新版推荐用 async/await避免这个问题。如果你混用回调和 Promise注意别把回调漏掉。5.5 环境变量读不到process.env.MONGO_URI返回 undefined通常是.env没被加载。确认在入口文件顶部调用了require(dotenv).config()且.env在项目根目录。TaoToken 的 Key 同理读不到就检查变量名拼写。6. 把 Key 通道接进项目下一步怎么走数据层跑通之后你可能会想在这个项目里接入模型能力比如让 Node.js 服务调用对话接口。这时候统一 Key 就派上用场了。TaoToken 的模型对话入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 可以先在网页上验证模型是否可用。如果你是要做长期编码或 Agent 类项目建议看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它更适合持续调用的场景。Claude Code 相关的接入说明在 https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecode-anthropicutm_campaignrewrite 需要的话对照配置。回到 Mongoose 本身最后给你一个实用习惯把 CRUD 操作封装成 service 层函数别在路由里直接写 Model 调用。这样后面加校验、加日志、换数据库都只改一处。数据层稳了上层怎么变都不慌。
RELATED READING

延伸阅读

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