You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB/Express问题:Array.includes为何返回false而非true?

解决投票应用中用户已投票判断失效的问题

我明白你遇到的麻烦了——明明数据库里已经把测试用户ID加到votedBy数组里,但判断用户是否已投票的逻辑却一直返回false。这个问题的核心其实是Mongoose ObjectId和字符串类型不匹配导致的,咱们一步步来修复它。

问题根源分析

你的Poll模型里,votedBy字段定义的是[{ type: Schema.Types.ObjectId, ref: 'User' }],也就是说这个数组里存储的是Mongoose的ObjectId对象,而你传入的voterId大概率是字符串格式的用户ID。直接用数组的includes()方法比较时,因为类型不同(对象 vs 字符串),所以永远匹配不上,返回false。

修复方案

你可以通过以下几种方式来修正这个判断逻辑,这里推荐最直接的两种:

方案1:将voterId转换为ObjectId后再比较

先把字符串格式的voterId转换成Mongoose的ObjectId类型,再用includes()判断:

// 先导入mongoose(如果控制器里还没导入的话)
import mongoose from 'mongoose';

// 修改hasVoted的计算逻辑
const hasVoted = poll.votedBy.includes(mongoose.Types.ObjectId(voterId));

方案2:将votedBy数组元素转为字符串后比较

把votedBy数组里的每个ObjectId都转换成字符串,再和字符串类型的voterId比较:

const hasVoted = poll.votedBy.map(id => id.toString()).includes(voterId);

额外优化建议

另外,你代码里的判断顺序可以调整一下,先检查用户是否登录(!voterId),再判断是否已投票,这样逻辑更合理,也能避免不必要的计算;同时poll.save()要加上await确保保存成功:

// 调整后的判断逻辑
if (!voterId) {
  res.status(400).json({ message: 'Sorry, you must be logged in to vote' });
} else {
  // 这里再计算hasVoted
  const hasVoted = poll.votedBy.includes(mongoose.Types.ObjectId(voterId));
  if (hasVoted) {
    res.status(400).json({ message: 'Sorry, you can only vote once' });
  } else {
    // 执行投票逻辑
    await choice.set(votedChoice);
    poll.votedBy.push(voterId);
    await poll.save(); // 加上await确保数据保存完成
    res.status(200).json({ 
      message: 'Thank you for voting. Find other polls at: ', 
      poll 
    });
  }
}

验证修复效果

修改后,用你数据库里的测试用户ID再测试一次,应该就能正确返回true,拦截重复投票了。

内容的提问来源于stack exchange,提问作者Collins Orlando

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:11:56