Mongoose如何查询数组字段是否含指定值并返回布尔结果
Mongoose 重复关注校验查询实现
实现原理
MongoDB 原生支持数组字段的包含匹配,不需要手动遍历followers数组:查询时直接给数组字段赋值要匹配的目标值,MongoDB 会自动检索数组内是否存在对应元素,配合User.exists()方法即可直接返回布尔值,标识是否已存在关注关系。
注意:你原有代码的判断逻辑写反了:
exists()返回true代表用户已经在粉丝列表中,属于已关注状态,应该返回重复关注提示;返回false才代表未关注,可以执行后续关注逻辑。
具体查询写法
因为你Schema中Id字段定义为ObjectId类型,followers数组内存储的用户ID通常也为ObjectId类型,查询时需要先把传入的字符串参数转为ObjectId避免类型不匹配,exists()内传入的查询条件如下:
// 记得在文件顶部引入mongoose const mongoose = require('mongoose'); // exists方法内的查询条件 { Id: new mongoose.Types.ObjectId(req.params.id), followers: new mongoose.Types.ObjectId(req.body.userId) }
修正后的完整路由代码
const User = require("../models/users"); const mongoose = require('mongoose'); router.put("/followuser/:id", async (req, res) => { // 不能关注自己的校验 if (req.params.id === req.body.userId) { return res.status(400).json("Cannot follow yourself mate") } // 校验是否已经关注 const hasFollowed = await User.exists({ Id: new mongoose.Types.ObjectId(req.params.id), followers: new mongoose.Types.ObjectId(req.body.userId) }) if (hasFollowed) { // 已关注返回错误 return res.status(400).json("You Already follow the user") } // 未关注则执行后续关注逻辑 // further code to allow following the user })
补充说明
- 如果你设计的
followers数组内存储的是字符串类型的用户ID,不需要调用new mongoose.Types.ObjectId()做类型转换,直接传入请求参数即可。 - 如果你需要兼容字符串和ObjectId两种类型的匹配,可以用
$in操作符,写法为followers: { $in: [req.body.userId, new mongoose.Types.ObjectId(req.body.userId)] },但更推荐从存储层面统一ID类型,减少额外兼容逻辑。 exists()方法相比findOne()性能更优,它不会返回完整的文档内容,仅返回匹配结果的布尔值,非常适合这类存在性校验场景。
内容的提问来源于stack exchange,提问作者Nikhil Udgata
相关产品推荐
相关产品推荐

