使用Mongoose调用collection的aggregate方法报同步错误如何解决?
问题根源
- 你直接调用
createConnection返回的连接实例上的collection()方法获取原生集合对象,Mongoose 6及更高版本中,连接未就绪时调用原生集合的异步方法如果没有传入回调函数,就会抛出Collection method xxx is synchronous错误 - 你没有等待mongoose连接建立完成就直接调用了集合方法,此时连接还处于pending状态,拿到的原生集合实例未初始化完成
修复方案
方案1:等待连接就绪后用Mongoose Model调用aggregate(最推荐)
符合Mongoose常规使用逻辑,无需直接操作原生集合:
import mongoose from 'mongoose'; // 等待连接建立完成 const Conn = await mongoose.createConnection('mongodb://127.0.0.1:27017/db').asPromise(); // 定义对应集合的Model const User = Conn.model('User', new mongoose.Schema({ ethAddr: String }), 'users'); // 调用aggregate加await获取结果 const addresses = await User.aggregate([ { $project: { _id: false, ethAddr: true, } } ]);
方案2:给原生aggregate方法传入回调函数
如果必须直接操作原生collection,可以传入回调获取结果:
const Conn = mongoose.createConnection('mongodb://127.0.0.1:27017/db'); Conn.on('open', () => { Conn.collection('users').aggregate([ { $project: { _id: false, ethAddr: true, } } ], (err, result) => { if (err) throw err; const addresses = result; // 后续逻辑写在回调内 }); });
方案3:等待连接就绪后调用原生aggregate并转为Promise
const Conn = await mongoose.createConnection('mongodb://127.0.0.1:27017/db').asPromise(); const addresses = await Conn.collection('users').aggregate([ { $project: { _id: false, ethAddr: true, } } ]).toArray();
注意事项
- 所有数据库操作都需要保证连接已经成功建立,不要在连接未就绪的状态下调用集合方法
- 优先使用Mongoose封装好的Model方法,可以避免绝大多数原生集合操作的兼容性问题
内容的提问来源于stack exchange,提问作者user8555937
相关产品推荐
相关产品推荐

