【问题标题】:Is there a way in mongoose to not create a collection if not found?如果找不到,猫鼬有没有办法不创建集合?
【发布时间】:2022-02-04 19:41:03
【问题描述】:

我们正在为基于团队的任务管理创建一个不和谐机器人。我们正在使用一个集合作为一个团队。在查找团队并向其添加任务的代码中,我们使用:const Team = await mongoose.connection.collection(teamName, {strict: true});strict 应该这样做,以便在找不到集合时不会创建集合,而是会发生这种情况:

我试过没有运气,因为猫鼬没有关于选项的文档,而且我尝试过的一切都不起作用。

如果teamName 不是集合名称/未找到,我如何让mongoose.connection.collection(teamName) 返回错误?

【问题讨论】:

  • 您可以检查数据库中是否存在集合,并根据它执行一些操作(例如,抛出错误)。
  • 正是我想要实现的目标,mongoose.connection.collection(collection name) 是这样做的方法,但我不希望它创建已经存在的集合。如果找不到,该方法会创建集合。

标签: javascript mongodb mongoose discord.js


【解决方案1】:

你是对的,strict: true 应该这样做,但没有。 Mongoose 没有提及它接受的选项,尽管通常它采用底层 mongo 客户端使用的选项。 但它确实在documentation 中提到它会丢失集合:

检索一个集合,如果没有缓存则创建它。

我查看了repocollection 方法总是会丢失集合

Connection.prototype.collection = function(name, options) {
 const defaultOptions = {
   autoIndex: this.config.autoIndex != null ? this.config.autoIndex : >this.base.options.autoIndex,
   autoCreate: this.config.autoCreate != null ? this.config.autoCreate : >this.base.options.autoCreate
 };
 options = Object.assign({}, defaultOptions, options ? utils.clone(options) : {});
 options.$wasForceClosed = this.$wasForceClosed;
 if (!(name in this.collections)) {
   this.collections[name] = new Collection(name, this, options);
 }
 return this.collections[name];
};

mongo-client collection 确实采用了严格的参数。 您可以通过mongoose.connection.client.db()访问它

更新

你可以这样称呼它:

mongoose.connection.client.db().collection(teamName, {strict: true}, function (error, collection) {
  console.log('error', error);
  console.log('collection', collection);
})

示例

>
> mongoose.connection.client.db().collection('nonExistantCollectionName', {strict: true}, function () { console.log(arguments) })
undefined
> [Arguments] {
  '0': MongoError: Collection nonExistantCollectionName does not exist. Currently in strict mode.
      at Function.create (./node_modules/mongodb/lib/core/error.js:57:12)
      at toError (./node_modules/mongodb/lib/utils.js:130:22)
      at ./node_modules/mongodb/lib/db.js:482:9
      at ./node_modules/mongodb/lib/utils.js:704:5
      at handleCallback (./node_modules/mongodb/lib/utils.js:109:55)
      at ./node_modules/mongodb/lib/cursor.js:840:66
      at ./node_modules/mongodb/lib/utils.js:704:5
      at ./node_modules/mongodb/lib/cursor.js:925:9
      at CommandCursor._endSession (./node_modules/mongodb/lib/core/cursor.js:397:7)
      at ./node_modules/mongodb/lib/cursor.js:923:12
      at maybePromise (./node_modules/mongodb/lib/utils.js:692:3)
      at CommandCursor.close (./node_modules/mongodb/lib/cursor.js:916:12)
      at ./node_modules/mongodb/lib/cursor.js:840:27
      at ./node_modules/mongodb/lib/core/cursor.js:739:9
      at handleCallback (./node_modules/mongodb/lib/core/cursor.js:32:5)
      at ./node_modules/mongodb/lib/core/cursor.js:683:38
      at _setCursorNotifiedImpl (./node_modules/mongodb/lib/core/cursor.js:696:10)
      at setCursorNotified (./node_modules/mongodb/lib/core/cursor.js:683:3)
      at done (./node_modules/mongodb/lib/core/cursor.js:458:16)
      at queryCallback (./node_modules/mongodb/lib/core/cursor.js:503:20)
      at ./node_modules/mongodb/lib/core/cursor.js:548:9
      at ./node_modules/mongodb/lib/utils.js:704:5
      at executeCallback (./node_modules/mongodb/lib/operations/execute_operation.js:65:7)
      at callbackWithRetry (./node_modules/mongodb/lib/operations/execute_operation.js:112:14)
      at ./node_modules/mongodb/lib/operations/command_v2.js:102:9
      at ./node_modules/mongodb/lib/core/connection/pool.js:405:18
      at processTicksAndRejections (internal/process/task_queues.js:79:11) {
    driver: true
  },
  '1': null
}


【讨论】:

  • 好的,我试试看!那么这是一个错误吗?
  • 不是一个错误,它甚至在文档中说它会这样做。它与mongo-client 的工作方式不同,这对于connection 方法来说是不寻常的。
  • .client.collection 似乎不存在,我试过 .getClient().collection 但集合不存在。
  • @YTGAMEWORKS 你是对的,我的语法错误。 collection 方法在客户端的数据库实例上。我更新了我的例子。它在不使用回调调用时会引发错误,但如果需要异步,您可以将其包装在 Promise 中。
  • 有效!原来这是一个 if 阻止你给我的代码执行。
【解决方案2】:

您可以使用此代码检查特定数据库中是否存在集合 - 然后根据需要执行操作。

const mongoose = require('mongoose');
const uri = 'mongodb://127.0.0.1:27017/';
const opts = { 
    useNewUrlParser: true, 
    useUnifiedTopology: true, 
    dbName: 'test' 
};

(async () => {
    const conn = await mongoose.createConnection(uri, opts);
    let collNames = await conn.db.listCollections().toArray();
    collNames = collNames.map(e => e.name);
    console.log(collNames);
    console.log(collNames.includes('existing_coll'));       // true
    console.log(collNames.includes('non_existing_coll'));   // false
    await conn.close();
})(uri, opts);

【讨论】:

  • 是的,可以试试,但我真的很想用mongoose.Connection#collection(teamName) 方法来做到这一点,更重要的是我想知道为什么它不起作用,而且它看起来更像整洁 :D 但如果我想不通就用这个!
  • 我认为 Mongoose 没有直接列出和检查集合名称(或它们的存在)的方法。 db.listCollections().toArray() 是原生 MongoDB NodeJS 驱动 API。
  • 你也可以在猫鼬中做一些非常相似的事情。
猜你喜欢
  • 2021-09-03
  • 2016-07-10
  • 1970-01-01
  • 2012-09-29
  • 2020-03-23
  • 1970-01-01
  • 2017-12-03
  • 2023-03-26
  • 2020-12-07
相关资源
最近更新 更多