You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS中MongoDB动态集合查询遇Mongoose超时错误求助

解决NestJS中MongoDB动态集合查询的超时问题

问题根源

你当前的实现每次调用DynamicSchema都会创建全新的Mongoose模型,且直接使用全局mongoose.model()方法,存在两个核心问题:

  • 重复注册同名模型(均为'Log')会引发Mongoose内部冲突
  • 动态创建的模型未关联到NestJS初始化好的数据库连接池,导致数据库操作处于缓冲等待状态,最终触发超时

解决方案

核心思路是复用已创建的模型并绑定到NestJS的数据库连接,具体步骤如下:

1. 注入NestJS的Mongoose连接

在服务中通过@InjectConnection()获取Nest初始化的数据库连接,确保动态模型使用正确的连接池。

2. 实现模型复用逻辑

每次创建前检查连接中是否已存在对应集合的模型,避免重复创建;用集合名称作为模型名,保证唯一性。

3. 替换废弃的计数方法

Mongoose已废弃count()方法,改用countDocuments()替代。

完整代码示例

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';
import { Prop, SchemaFactory } from '@nestjs/mongoose';

@Injectable()
export class LogService {
  constructor(@InjectConnection() private readonly connection: Connection) {}

  // 获取动态日志模型,复用已存在的模型
  private getDynamicLogModel(collectionName: string) {
    // 检查当前连接中是否已注册该集合的模型
    if (this.connection.models[collectionName]) {
      return this.connection.models[collectionName];
    }

    // 动态定义Schema
    @Schema({ collection: collectionName })
    class DynamicLog {
      @Prop()
      level: string;

      @Prop()
      message: string;
    }

    const dynamicLogSchema = SchemaFactory.createForClass(DynamicLog);
    // 以集合名作为模型名注册,避免重复冲突
    return this.connection.model(collectionName, dynamicLogSchema);
  }

  async queryLogs(gatewayId: string, options: Record<string, any>) {
    const dynamicModel = this.getDynamicLogModel(gatewayId);
    
    // 执行查询并强制调用exec()确保Promise正确解析
    const logs = await dynamicModel.find(options).limit(2).exec();
    const totalDocuments = await dynamicModel.countDocuments(options).exec();
    
    return { logs, totalDocuments };
  }
}

关键优化点说明

  • 复用模型:避免重复创建模型导致的连接冲突和资源浪费
  • 绑定Nest连接:确保模型使用Nest初始化的数据库连接,而非全局未初始化的连接
  • 显式调用exec():Mongoose的查询构建器需要通过exec()返回标准Promise,避免异步处理异常

内容的提问来源于stack exchange,提问作者Rafael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:31:19