从MongoDB查询5个随机用户却返回空数组该如何修复
问题原因
- 你代码中的
countDocuments、findOne都属于异步IO操作,对应的回调函数会在所有同步代码执行完毕后才触发。你在循环结束后直接调用res.send(arr)时,所有数据库查询操作还没完成,数组自然是空的。 - 循环多次查询数据库的写法性能极低,当集合数据量较大时,
skip操作本身也会产生明显的性能损耗。
修复方案
方案1:基于原有逻辑的异步改造(适合小数据集场景)
用async/await改写逻辑,保证所有查询执行完成后再返回结果:
async function getRandomUsers() { const arr = [] const count = await User.countDocuments().exec() for (let i = 0; i < 5; i++ ){ const random = Math.floor(Math.random() * count) const result = await User.findOne().skip(random).exec() arr.push(result) } return arr } // 路由处理函数需要标记为async app.get('你的路由地址', async (req, res) => { try { const arr = await getRandomUsers() res.send(arr) } catch (err) { res.status(500).send('查询失败') } })
方案2:使用MongoDB原生聚合(性能更优,推荐使用)
MongoDB内置的$sample聚合算子原生支持随机取样,不需要手动循环查询,性能远高于第一种方案:
// 路由处理函数需要标记为async app.get('你的路由地址', async (req, res) => { try { const arr = await User.aggregate([ { $sample: { size: 5 } } // 直接从集合中随机取5个文档 ]).exec() res.send(arr) } catch (err) { res.status(500).send('查询失败') } })
内容的提问来源于stack exchange,提问作者King Of Chads
相关产品推荐
相关产品推荐

