MongoDB find().count()数据传递问题:Express应用查询故障排查
问题根源分析
你遇到的错误核心在于Promise链的数据传递中断:
当你在find()之后调用count()时,这个操作会将Promise链的返回值替换为计数结果(一个数字),而不是之前find()查询到的用户数组。所以第二个then()里的profileArray实际上是undefined,尝试访问undefined[0]自然会抛出TypeError。
解决方案
方案1:直接通过查询结果的长度判断(推荐,减少一次数据库请求)
不需要额外调用count(),直接在find()的回调里检查返回数组的长度,这样既保留了查询到的用户数据,又能完成存在性校验:
app.get('/profiles/:name', (req, res) => { // 调用Profile模型 Profile.find({ "name.first": req.params.name }) .then(profileArray => { // 校验用户是否存在 if (profileArray.length < 1) { return Promise.reject({ code: 404, reason: "ValidationError", message: "Profile not found. Please create a profile." }); } // 存在则继续处理渲染逻辑 let profile = profileArray[0]; let img = `<img class="ui rounded image" src="http://api.adorable.io/avatar/250/${profile.name.first}${profile.age}" />` res.render('profile', { profile, img }); }) .catch(error => { if (error.reason === "ValidationError") { console.log(error); let response404 = error; res.render('add', { response404 }); } else { console.log(error); res.render('add'); } }); });
方案2:使用findOne()简化代码(更优)
既然你只需要匹配到的第一个用户,完全可以用findOne()代替find(),它直接返回单个文档,不需要再取数组下标,代码更简洁:
app.get('/profiles/:name', (req, res) => { Profile.findOne({ "name.first": req.params.name }) .then(profile => { if (!profile) { // 直接判断文档是否存在 return Promise.reject({ code: 404, reason: "ValidationError", message: "Profile not found. Please create a profile." }); } let img = `<img class="ui rounded image" src="http://api.adorable.io/avatar/250/${profile.name.first}${profile.age}" />` res.render('profile', { profile, img }); }) .catch(error => { if (error.reason === "ValidationError") { console.log(error); let response404 = error; res.render('add', { response404 }); } else { console.log(error); res.render('add'); } }); });
为什么原代码正常?
原代码中find()之后直接进入then(),回调参数profileArray就是查询到的用户数组,没有中间操作替换Promise的返回值,所以能正常获取到用户数据并渲染页面。
内容的提问来源于stack exchange,提问作者bprdev
相关产品推荐
相关产品推荐

