如果在调用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/

10-16 09:43