MongoDB aggregate查询执行正常但方法返回结果为空如何解决?
问题原因
- 核心是异步执行时序问题:MongoDB的
aggregate方法返回Promise对象,属于异步操作,不会阻塞主线程执行。你写的for循环触发4次异步查询后,函数会直接执行return result,此时所有异步查询的then回调还未触发,result仍保持初始的空字符串值。 - 控制台能打印中间结果,是因为异步回调在函数返回后才陆续执行,此时修改的
result已经无法被函数返回值捕获。
解决方案
推荐使用async/await改写异步逻辑,保证所有数据库查询执行完成后再返回结果,示例代码如下:
async function f(hwUsers, num){ let result = ''; try { for(let n of num){ // 等待当前查询完成再执行下一轮循环 const hwu = await hwUsers.aggregate([ {"$match": {num: n}}, {"$project":{str: 1, _id: 0}} ]); hwu.forEach(item => { result += item.str; }); } return result; } catch(err) { console.log(err); throw err; } } // 调用时需要用await或者then获取返回值 // 方法1:在异步函数内用await接收 async function getRes() { const resStr = await f(hwUsers, numbers); // 处理resStr的逻辑写在这里 } // 方法2:用then接收返回值 f(hwUsers, numbers).then(resStr => { // 处理resStr的逻辑写在这里 })
如果需要更高的查询效率,也可以一次性查询所有符合条件的分片,再按顺序拼接,避免循环查询数据库:
async function f(hwUsers, nums){ try { const hwuList = await hwUsers.aggregate([ {"$match": {num: {"$in": nums}}}, {"$sort": {num: 1}}, // 按num排序保证拼接顺序正确 {"$project":{str: 1, _id: 0}} ]); return hwuList.map(item => item.str).join(''); } catch(err) { console.log(err); throw err; } }
内容的提问来源于stack exchange,提问作者user17065575
相关产品推荐
相关产品推荐

