合并NodeJS项目后,如何为不同路由使用不同MongoDB集合?
解决方案:为不同路由绑定独立MongoDB数据库连接
要解决合并项目后不同路由对应不同MongoDB集合/数据库的问题,核心是让每个项目的模型绑定到独立的数据库连接实例,而非共用mongoose的全局默认连接。以下是具体重构步骤:
1. 重构数据库连接文件(db.js)
将原有的全局连接改为创建主连接,并为两个项目分别生成数据库实例,再绑定对应的模型:
const config = require('config'); const mongoose = require('mongoose'); // 创建主连接(连接到MongoDB服务器,不指定具体数据库) const mainConnection = mongoose.createConnection(process.env.MONGODB_URI || config.get('connectionString'), { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true }); // 为两个项目分别获取对应的数据库实例 const squareDb = mainConnection.useDb('squareCollection'); // Project1对应的数据库名 const defaultDb = mainConnection.useDb('defaultCollection'); // Project2对应的数据库名 mongoose.Promise = global.Promise; // 导出分属不同项目的模型,绑定到对应数据库实例 module.exports = { // Project1的模型集合 squareModels: { SquareRating: squareDb.model('SquareRating', require('../project1-server-backend/users/rating.model')), // 其他Project1模型按此格式添加 }, // Project2的模型集合 defaultModels: { Rating: defaultDb.model('Rating', require('../project2-server-backend/users/rating.model')), Image: defaultDb.model('Image', require('../project2-server-backend/images/images.model')), // 其他Project2模型按此格式添加 }, mainConnection, squareDb, defaultDb };
2. 修改模型文件,仅导出Schema
原模型文件直接创建了绑定全局连接的模型,现在需要改为仅导出Schema,让db.js根据不同数据库实例创建模型:
以Project1的rating.model.js为例:
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const schema = new Schema({ rating: { type: Number, unique: false, required: true }, orgUuid: { type: String, required: true }, note: { type: String, unique: false, required: false}, }); schema.set('toJSON', { virtuals: true }); module.exports = schema; // 只导出Schema,不再创建全局模型
Project2的所有模型文件也做同样修改。
3. 在服务层使用对应项目的模型
修改两个项目的服务代码,调用对应数据库实例的模型:
Project1服务示例
const db = require('../../_helpers/db'); // 根据实际路径调整 const SquareRating = db.squareModels.SquareRating; async function getRatingById(id) { return SquareRating.find({ orgUuid: id }); // 匹配Schema中的字段 }
Project2服务示例
const db = require('../../_helpers/db'); // 根据实际路径调整 const Rating = db.defaultModels.Rating; async function getRatingById(id) { return Rating.find({ id: id }); }
4. 等待数据库连接就绪后启动服务器
解决buffering timed out错误,确保所有数据库连接就绪后再加载路由、启动服务:
在server.js中修改启动逻辑:
const express = require('express'); const app = express(); const db = require('./_helpers/db'); // 等待所有数据库连接就绪 Promise.all([ db.mainConnection.asPromise(), db.squareDb.asPromise(), db.defaultDb.asPromise() ]).then(() => { // 加载路由 app.use('/api/square/users', require('./project1-server-backend/users/users.controller')); app.use('/api/users', require('./project2-server-backend/users/users.controller')); const port = process.env.PORT || 3000; app.listen(port, () => console.log(`Server running on port ${port}`)); }).catch(err => { console.error('数据库连接失败:', err); process.exit(1); });
关键说明
- 为什么之前的
useDb无效?因为原模型绑定的是mongoose全局默认连接,后续切换数据库实例不会改变已创建模型的绑定关系,必须让模型从创建时就绑定到目标数据库实例。 createConnection与mongoose.connect的区别:前者创建独立连接实例,便于管理多数据库;后者创建全局默认连接,适合单数据库场景。
内容的提问来源于stack exchange,提问作者coder123
相关产品推荐
相关产品推荐

