如何在Node.js CLI中同时连接多个Mongo Atlas数据库并实现读写?
多MongoDB连接与模型处理方案
问题解答与代码修正
1. 如何在同一应用中建立两个同时有效的数据库连接?
你之前的代码用mongoose.connect()两次会覆盖默认连接,导致只有最后一次连接生效。正确做法是使用mongoose.createConnection()创建独立的连接实例,每个实例对应一个数据库:
修改ReadDB.js:
require('dotenv').config(); const mongoose = require('mongoose'); const read_db_url = process.env.READDB_URI; const readDB = async () => { try { // 创建独立的读数据库连接实例 const readConnection = await mongoose.createConnection(read_db_url, { useNewUrlParser: true, useUnifiedTopology: true, dbName: "dbProd" }); console.log("读数据库连接成功"); return readConnection; } catch (err) { console.error("读数据库连接失败:", err); throw err; } } module.exports = readDB;
修改WriteDB.js:
require('dotenv').config(); const mongoose = require('mongoose'); const write_db_url = process.env.WRITEDB_URI; const writeDB = async () => { try { // 创建独立的写数据库连接实例 const writeConnection = await mongoose.createConnection(write_db_url, { useNewUrlParser: true, useUnifiedTopology: true, dbName: "dbQA" }); console.log("写数据库连接成功"); return writeConnection; } catch (err) { console.error("写数据库连接失败:", err); throw err; } } module.exports = writeDB;
2. 是否需要为读写分别创建独立模型?
是的。模型与特定数据库连接绑定,读写操作对应不同数据库,因此需要为每个连接创建独立的模型实例。不过Schema可以复用,无需重复定义:
先定义通用的产品Schema(可单独抽离为productSchema.js):
const mongoose = require('mongoose'); module.exports = new mongoose.Schema({ name: String, price: Number, // 其他字段与原数据库保持一致 });
然后在主程序中基于不同连接创建模型:
const productSchema = require('./productSchema.js'); // 基于读连接创建读模型 const ProductRead = readConnection.model('Product', productSchema, 'products'); // 基于写连接创建写模型 const ProductWrite = writeConnection.model('Product', productSchema, 'products');
3. Node.js如何识别读取操作对应的数据库?
通过模型绑定的连接实例区分。每个模型都关联着一个特定的MongoDB连接,调用模型的查询/写入方法时,操作会自动路由到该模型绑定的数据库连接上。比如ProductRead.find()会从读数据库查询,ProductWrite.save()会写入到写数据库。
完整主程序示例(cli.js)
require('dotenv').config(); const connectReadDB = require('./ReadDB.js'); const connectWriteDB = require('./WriteDB.js'); const productSchema = require('./productSchema.js'); async function main() { // 初始化两个独立连接 const readConnection = await connectReadDB(); const writeConnection = await connectWriteDB(); // 创建绑定到对应连接的模型 const ProductRead = readConnection.model('Product', productSchema, 'products'); const ProductWrite = writeConnection.model('Product', productSchema, 'products'); // 读取产品函数 const findProduct = async (productId) => { try { return await ProductRead.findById(productId); } catch (err) { console.error("读取产品失败:", err); throw err; } }; // 写入产品函数 const writeProduct = async (productData) => { try { const newProduct = new ProductWrite(productData); await newProduct.save(); console.log(`产品 ${productData._id} 写入成功`); return newProduct; } catch (err) { console.error("写入产品失败:", err); throw err; } }; // 示例:读取并写入单个产品 const targetProductId = "your-target-product-id"; const product = await findProduct(targetProductId); if (product) { // 转换为普通对象,避免mongoose文档对象的额外属性 await writeProduct(product.toObject()); } } // 启动程序 main().catch(err => console.error("程序执行出错:", err));
内容的提问来源于stack exchange,提问作者SJaka
相关产品推荐
相关产品推荐

