MongoDB原生驱动连接成功但db对象为undefined,如何获取集合字段名?
MongoDB连接后db对象为undefined?看这里解决!
嘿,我仔细看了你的代码,发现核心问题出在LoopBack MongoDB连接器的connect方法回调参数的理解上——你以为回调会返回原生的MongoDB db对象,但实际上这个回调只有一个错误参数,所以你的mdb变量自然是undefined!
为什么会这样?
LoopBack的mongoConnector.connect()方法的设计是:回调函数只接收一个err参数,连接成功后,原生的MongoDB Db对象已经挂载在连接器实例的db属性上了,不需要从回调里获取。
修正后的代码
我帮你调整了代码,不仅解决了mdb undefined的问题,还优化了几个细节:
Activation.getUserFields = function (id, callbackFn) { const connector = Activation.app.dataSources.mongoConnector; // 触发连接(如果未连接的话) connector.connect(function (errconnect) { if (errconnect) { console.error('连接失败:', errconnect); return callbackFn(errconnect, {}); } // 从连接器获取原生MongoDB Db对象 const mdb = connector.db; console.log('原生db对象:', mdb); // 执行mapReduce获取所有字段名 mdb.runCommand({ "mapreduce": "Visit", "map": function () { // 遍历当前文档的所有键 for (var key in this) { emit(key, null); } }, "reduce": function (key, stuff) { // reduce阶段不需要处理,直接返回null return null; }, "out": { inline: 1 } // 直接返回结果,避免创建临时集合,更高效 }, function(err, mrResult) { if (err) { console.error('mapReduce失败:', err); return callbackFn(err, {}); } // 从结果中提取所有字段名 const fieldNames = mrResult.results.map(item => item._id); callbackFn(null, fieldNames); }); }); };
几个关键优化点:
- 去掉了错误的
mdb回调参数,改用connector.db获取原生db对象 - 把
runCommand改成带回调的形式(你之前的写法是同步的,但MongoDB驱动的runCommand是异步的,需要回调) - 使用
inline输出的mapReduce,不需要创建临时集合再查询,节省资源 - 增加了错误日志,方便排查问题
额外提示
如果你操作的是LoopBack已经定义的模型(比如Visit是你在LoopBack里创建的模型),其实可以直接用LoopBack的API获取字段,比如:
const visitModel = Activation.app.models.Visit; const fields = Object.keys(visitModel.definition.properties); callbackFn(null, fields);
这种方式更简单,不过如果Visit是动态创建的集合(没有对应的LoopBack模型),那原生驱动的mapReduce方式更合适。
内容的提问来源于stack exchange,提问作者Ankur
相关产品推荐
相关产品推荐

