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

Mongoose调用Collection.find报is synchronous错误,findOne运行正常

问题现象

仅在调用集合的find方法时触发错误,findOne方法可正常运行,触发的报错信息如下:

throw new Error('Collection method ' + i + ' is synchronous');

代码逻辑为封装MongoDB连接逻辑后,在异步函数中通过await调用集合的find方法,查询价格不低于200的商品数据并仅返回price字段,运行时直接抛出上述同步方法错误。

涉及代码

index.js

const mongoose = require("mongoose");
const { database } = require("./server");

database();

let db = mongoose.connection;
let Products = db.collection("Products");

async function FindProd() {
  let findProd = await Products.find(
    { price: { $gte: 200 } },
    { projection: { price: 1, _id: 0 } }
  );
  console.log(findProd);
}
FindProd();

server.js

const mongoose = require("mongoose");

let database = function () {
  mongoose.connect("mongodb://127.0.0.1:27017/mydb", (err, res) => {
    if (res) {
      console.log("connection successfull");
    } else {
      console.log("error:", err);
    }
  });
};

module.exports = { database };
问题成因
  • 代码调用database()发起数据库连接后,没有等待连接建立完成,就同步执行db.collection("Products")获取集合实例。此时数据库连接还处于待完成状态,拿到的是Mongoose提供的未就绪Collection代理对象,并非原生MongoDB驱动的可用Collection实例。
  • Mongoose对未就绪状态的集合方法做了占位处理:findOne这类直接返回文档结果的方法做了隐式等待兼容,会在连接就绪后自动执行;但find方法返回值是游标类型,占位逻辑为直接同步抛出错误,不会等待连接就绪,这就是报错的直接来源。
  • 代码还存在额外逻辑问题:即使连接状态正常,直接await Products.find()也无法拿到预期的查询结果——原生MongoDB驱动的find方法返回的是查询游标,不是结果Promise,需要调用游标上的toArray()等方法才能获取实际文档数据。
解决方法
  • 改造数据库连接逻辑,让连接方法返回Promise,所有数据库操作必须等待连接成功后再执行,禁止在连接发起阶段同步获取集合实例。
  • 修正find方法的调用逻辑,拿到查询游标后调用toArray()方法获取最终的查询结果数组。
  • 若不想手动管理连接状态,可直接使用Mongoose官方推荐的Schema/Model体系操作集合,Mongoose会自动处理连接等待、方法兼容问题。

修正后代码

server.js

const mongoose = require("mongoose");

let database = function () {
  return new Promise((resolve, reject) => {
    mongoose.connect("mongodb://127.0.0.1:27017/mydb", (err, res) => {
      if (res) {
        console.log("connection successfull");
        resolve(res);
      } else {
        console.log("error:", err);
        reject(err);
      }
    });
  })
};

module.exports = { database };

index.js

const mongoose = require("mongoose");
const { database } = require("./server");

async function run() {
  // 等待数据库连接完成
  await database();
  const db = mongoose.connection;
  const Products = db.collection("Products");

  // find返回游标,调用toArray获取结果数组
  const findProd = await Products.find(
    { price: { $gte: 200 } },
    { projection: { price: 1, _id: 0 } }
  ).toArray();
  console.log(findProd);
}

run();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:33:44