如果在调用drop()
时不存在该集合,则会引发错误:
目前我正在使用类似
try {
await MongooseModel.collection.drop();
} catch (err) {
if (err.message !== 'ns not found') {
throw err;
}
}
闻起来不太香目前尚不清楚为什么会首先引发错误,我希望
drop()
如果不存在,将返回false
,就像在Mongo控制台中所做的那样。当仅引用Mongoose模型
MongooseModel
时,该怎么办?我在执行此操作的地方没有对连接对象的引用,就像this answer中建议的那样。
最佳答案
实际上,您确实有引用。建立连接后,您可以随时mongoose.connection
并返回当前连接。
您也可以简单地从任何模型实例中获取 db
。因此,如果您不希望在集合不存在时对错误进行try..catch
编码,则可以使用一种方法,即基本上使用底层驱动程序中的 .listCollections()
方法,以查看要访问的集合是否确实存在于命名空间中第一的:
const mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
mongoose.set('debug',true);
const uri = 'mongodb://localhost/blank',
options = { useMongoClient: true };
const testSchema = new Schema({},{ strict: false });
const ModelA = mongoose.model('ModelA', testSchema);
const ModelB = mongoose.model('ModelB', testSchema);
(async function() {
try {
const conn = await mongoose.connect(uri,options);
await ModelB.create({ a: 1 });
for ( let model of [ModelA,ModelB] ) {
let list = await model.db.db.listCollections({
name: model.collection.name
}).toArray()
//console.log(JSON.stringify(list,undefined,2));
if ( list.length !== 0 ) {
await model.collection.drop();
} else {
console.log('collection %s does not exist',model.collection.name);
}
}
} catch(e) {
console.error(e);
} finally {
mongoose.disconnect();
}
将证明不存在第一次尝试的收集删除,而不会引发错误:
Mongoose: modelbs.insert({ a: 1, _id: ObjectId("59aa9cfe581cca7afac55181"), __v: 0 })
collection modelas does not exist
Mongoose: modelbs.drop()
您还可以执行其他操作,例如将基础驱动程序中的
.collection()
与{ strict: true }
一起使用,以首先获取集合对象。但是,这实际上只是“引发错误”。因此,尽管您在发出.drop()
之前不知道该集合不存在,但是仍然需要相同的try..catch
处理。因此,如果没有错误,请首先检查集合的存在。只要没有其他东西可以删除它,当然。但是您可能应该始终以错误处理方式以防万一。
就我个人而言,我确实发现它更干净,可以允许发生异常,然后仅检查详细信息以查看所引发的异常是我所期望的:
for ( let model of [ModelA,ModelB] ) {
try {
await model.collection.drop();
} catch (e) {
if (e.code === 26) {
console.log('namespace %s not found',model.collection.name)
} else {
throw e;
}
}
}
在这种情况下,
code: 26
表示"Namespace not found"
,在这种情况下,或者在将 native .collection()
方法与{ strict: true }
一起使用时,也会引发这种情况。但是使用现有句柄的.drop()
收集对象要短得多。要点是,什么都不需要您实际记录异常,而“检查异常”(即批量插入中预期的重复键错误)是一种常见的做法。只需测试预期的错误代码,然后“如果”返回其他内容,则可以在更高级别上引发异常。
如前所述,虽然您可以“假设”要求数据库按名称列出集合,并且该集合存在于结果中,那么该假设存在,但最安全的方法是仍然从I/O捕获任何异常是在“查询”和“操作”之间删除的其他一些修改。
关于node.js - 在放入 Mongoose 之前检查集合是否存在,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46013256/