Node.js MongoDB多表查询返回空数组问题求助
问题分析与解决方案
问题核心
你的代码之所以返回空数组,是因为异步操作的执行顺序没处理对:rooms.find是异步Promise操作,循环里发起这些请求后,你立刻就执行了console.log(finalArr)和res.end(),这时候所有房间查询还没完成,finalArr自然还没被填充。
可行解决代码
用async/await配合Promise.all,确保所有异步查询完成后再返回结果:
router.post('/find/', async (req, res, next) => { try { // 先查目标区域的所有酒店 const hotelsList = await hotels.find({ region: "wuse" }); // 为每个酒店生成查询对应房间的Promise const roomQueryPromises = hotelsList.map(hotel => rooms.find({ hotel: hotel._id, price: { $lt: 29000 } }) ); // 等待所有房间查询完成,拿到所有结果 const allRoomsGroups = await Promise.all(roomQueryPromises); // 把二维数组(每个酒店对应一组房间)扁平化,得到最终房间数组 const finalArr = allRoomsGroups.flat(); console.log(finalArr); res.json(finalArr); // 用res.json返回JSON数据,比res.end更规范 } catch (error) { console.error(error); res.status(500).json({ error: "数据查询失败" }); } });
关键改进点
- 把路由函数改成
async,内部用await等待异步操作完成,避免回调嵌套 - 用
map生成所有房间查询的Promise数组,再通过Promise.all一次性等待所有请求结束,保证所有数据都拿到后再处理 - 用
flat()简化数组扁平化操作,不用手动嵌套循环 - 用
res.json()替代res.end(),自动处理响应头和JSON格式,更适合接口返回 - 统一错误捕获,返回标准的错误状态码和信息
额外性能优化建议
如果你的MongoDB版本支持,直接用聚合查询关联两张表,一次查询完成所有操作,比多次查询数据库效率更高:
router.post('/find/', async (req, res, next) => { try { const result = await hotels.aggregate([ // 先筛选目标区域的酒店 { $match: { region: "wuse" } }, // 关联房间表,同时筛选价格符合要求的房间 { $lookup: { from: "rooms", // 你的房间集合名称 localField: "_id", foreignField: "hotel", as: "matchedRooms", pipeline: [{ $match: { price: { $lt: 29000 } } }] } }, // 展开房间数组 { $unwind: "$matchedRooms" }, // 把房间数据作为根文档返回,得到纯房间对象数组 { $replaceRoot: { newRoot: "$matchedRooms" } } ]); res.json(result); } catch (error) { console.error(error); res.status(500).json({ error: "数据查询失败" }); } });
内容的提问来源于stack exchange,提问作者Ogoh.cyril
相关产品推荐
相关产品推荐

