
在mongoose中,处理数据库连接主要有两种方式:使用mongoose.connect()建立默认连接,以及使用mongoose.createconnection()建立独立的连接实例。
默认连接 (mongoose.connect()): 当你调用mongoose.connect()时,Mongoose会建立一个全局的、默认的连接。此后,所有直接通过mongoose.model()定义和获取的模型都将绑定到这个默认连接上。这适用于大多数单数据库应用场景。
独立连接 (mongoose.createConnection()): 对于需要连接到多个数据库、或者需要对不同业务模块使用不同数据库连接的应用,mongoose.createConnection()是理想选择。它会返回一个独立的Connection实例,这个实例拥有自己的连接池和状态,与其他连接互不影响。这意味着你可以为每个数据库创建一个独立的连接对象,并在其上定义和操作模型,从而实现数据库操作的隔离。
const mongoose = require('mongoose');
// 统一的连接选项,可根据需要调整
const connectionOptions = {
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
};
// 建立第一个数据库连接
const dbEnConnection = mongoose.createConnection("mongodb://localhost/db_en", connectionOptions);
// 建立第二个数据库连接
const dbFrConnection = mongoose.createConnection("mongodb://localhost/db_fr", connectionOptions);
// 可以在连接成功或失败时进行监听
dbEnConnection.on('connected', () => console.log('Connected to db_en'));
dbEnConnection.on('error', (err) => console.error('db_en connection error:', err));
dbFrConnection.on('connected', () => console.log('Connected to db_fr'));
dbFrConnection.on('error', (err) => console.error('db_fr connection error:', err));当使用mongoose.createConnection()创建了独立的连接实例后,模型的定义和注册方式与默认连接有所不同。你必须在特定的连接实例上调用model()方法来注册模型,而不是在全局的mongoose对象上。
定义Schema: 首先,像往常一样定义你的Mongoose Schema。Schema是模型的骨架,它定义了文档的结构、数据类型和验证规则。Schema的定义与连接无关,可以在任何地方进行。
const priceSchema = new mongoose.Schema({
fixed: {
1: { type: Number, default: 199 },
3: { type: Number, default: 499 },
6: { type: Number, default: 729 },
12: { type: Number, default: 999 }
}
});
const productSchema = new mongoose.Schema({
name: { type: String, required: true },
price: { type: Number, required: true },
currency: { type: String, default: 'USD' }
});在特定连接上注册模型并获取构造函数: 关键在于使用连接实例的model()方法来注册Schema。这个方法接收两个参数:模型名称(字符串)和Schema对象。最重要的是,它会返回一个可以直接用于创建新文档的模型构造函数。
// 在db_enConnection上注册Price模型
// PriceModelEn 就是一个构造函数
const PriceModelEn = dbEnConnection.model('Price', priceSchema);
// 在db_frConnection上注册Product模型
// ProductModelFr 也是一个构造函数
const ProductModelFr = dbFrConnection.model('Product', productSchema);一旦你通过connection.model()方法获取了模型构造函数,就可以使用它来创建新的文档实例,并执行保存、查询等操作。
// 使用db_enConnection上的Price模型
async function createPriceDocument() {
// 正确的实例化方式:使用获取到的模型构造函数
const priceDoc = new PriceModelEn();
try {
await priceDoc.save(); // 使用await确保异步操作完成
console.log('价格文档已保存到 db_en:', priceDoc);
} catch (error) {
console.error('保存价格文档到 db_en 失败:', error);
}
}
// 使用db_frConnection上的Product模型
async function createProductDocument() {
// 正确的实例化方式:使用获取到的模型构造函数
const productDoc = new ProductModelFr({ name: 'French Baguette', price: 2.50 });
try {
await productDoc.save();
console.log('产品文档已保存到 db_fr:', productDoc);
} catch (error) {
console.error('保存产品文档到 db_fr 失败:', error);
}
}错误解析:TypeError: conn.Price is not a constructor
这个错误通常发生在尝试像访问对象属性一样访问模型时,例如new conn.Price()。Mongoose的Connection对象并没有一个名为Price的直接属性来作为模型构造函数。当你调用conn.model('Price', priceSchema)时,它是在该连接实例上注册了一个名为'Price'的模型,并且返回了这个模型的构造函数。因此,你必须捕获这个返回值,并使用它来实例化文档。
区分 mongoose.model() 和 connectionInstance.model()
务必根据你使用的连接类型来选择正确的方法。
最佳实践:
下面是一个整合了上述概念的完整示例,展示了如何使用两个独立的Mongoose连接来操作不同数据库中的模型。
const mongoose = require('mongoose');
// 统一的连接选项
const connectionOptions = {
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
};
// --- 第一数据库连接:db_en ---
const dbEnConnection = mongoose.createConnection("mongodb://localhost/db_en", connectionOptions);
dbEnConnection.on('connected', () => console.log('Successfully connected to db_en'));
dbEnConnection.on('error', (err) => console.error('db_en connection error:', err));
dbEnConnection.on('disconnected', () => console.log('Disconnected from db_en'));
// 定义价格Schema
const priceSchema = new mongoose.Schema({
fixed: {
1: { type: Number, default: 199 },
3: { type: Number, default: 499 },
6: { type: Number, default: 729 },
12: { type: Number, default: 999 }
}
});
// 在db_enConnection上注册Price模型并获取构造函数
const PriceModelEn = dbEnConnection.model('Price', priceSchema);
// --- 第二数据库连接:db_fr ---
const dbFrConnection = mongoose.createConnection("mongodb://localhost/db_fr", connectionOptions);
dbFrConnection.on('connected', () => console.log('Successfully connected to db_fr'));
dbFrConnection.on('error', (err) => console.error('db_fr connection error:', err));
dbFrConnection.on('disconnected', () => console.log('Disconnected from db_fr'));
// 定义产品Schema
const productSchema = new mongoose.Schema({
name: { type: String, required: true },
price: { type: Number, required: true },
currency: { type: String, default: 'EUR' }
});
// 在db_frConnection上注册Product模型并获取构造函数
const ProductModelFr = dbFrConnection.model('Product', productSchema);
// --- 示例操作函数 ---
async function createPriceDocument() {
console.log('\n--- 尝试在 db_en 中创建价格文档 ---');
const priceDoc = new PriceModelEn(); // 使用正确的模型构造函数
try {
await priceDoc.save();
console.log('价格文档已成功保存到 db_en:', priceDoc);
} catch (error) {
console.error('保存价格文档到 db_en 失败:', error.message);
}
}
async function createProductDocument() {
console.log('\n--- 尝试在 db_fr 中创建产品文档 ---');
const productDoc = new ProductModelFr({ name: 'Laptop', price: 1200.00 });
try {
await productDoc.save();
console.log('产品文档已成功保存到 db_fr:', productDoc);
} catch (error) {
console.error('保存产品文档到 db_fr 失败:', error.message);
}
}
async function runAllExamples() {
await createPriceDocument();
await createProductDocument();
// 示例查询
console.log('\n--- 尝试从 db_en 查询价格文档 ---');
try {
const prices = await PriceModelEn.find({});
console.log('db_en 中的价格文档:', prices);
} catch (error) {
console.error('从 db_en 查询失败:', error.message);
}
console.log('\n--- 尝试从 db_fr 查询产品文档 ---');
try {
const products = await ProductModelFr.find({});
console.log('db_fr 中的产品文档:', products);
} catch (error) {
console.error('从 db_fr 查询失败:', error.message);
}
// 关闭所有连接
console.log('\n--- 关闭数据库连接 ---');
await dbEnConnection.close();
await dbFrConnection.close();
console.log('所有数据库连接已关闭。');
}
// 运行所有示例
runAllExamples().catch(console.error);通过本教程,我们深入理解了Mongoose中多数据库连接的管理策略。核心要点在于:当使用mongoose.createConnection()建立独立连接时,必须在该连接实例上调用connection.model()来注册和获取模型构造函数。避免直接将连接对象作为模型的容器(如conn.Price),因为这会导致TypeError。正确地使用connection.model()的返回值,将使你在Mongoose多数据库环境中高效、准确地进行数据操作。
以上就是Mongoose多数据库连接与模型管理深度解析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号