Mongoose聚合查询获取notifications内嵌数组返回空数组及元素操作咨询
NestJS中Mongoose操作User内嵌notifications数组问题解决
一、聚合查询返回空数组的修复
你的聚合查询返回空数组,核心原因是**userId类型与MongoDB文档中的_id类型不匹配**——文档里的_id是ObjectId类型,而你传入的userId大概率是字符串,导致$match阶段没有匹配到任何文档。
修复后的聚合查询代码
import { ObjectId } from 'mongoose'; // 先将字符串userId转换为ObjectId const targetUserId = new ObjectId(userId); const notifications = await this.userRepo.aggregate([ { $match: { _id: targetUserId } }, { $unwind: "$notifications" }, { $replaceRoot: { newRoot: "$notifications" } } ]);
更高效的替代方案(无需聚合)
如果只是要提取notifications数组,直接用findOne投影更简单:
const user = await this.userRepo.findOne( { _id: targetUserId }, { notifications: 1, _id: 0 } // 只返回notifications字段,排除_id ); const notifications = user?.notifications || [];
二、notifications数组单个元素的操作
1. 查询单个通知元素
通过$位置操作符,匹配并返回数组中符合条件的单个元素:
// 查询指定用户下某条特定_id的通知 const targetNotificationId = new ObjectId(notificationId); const result = await this.userRepo.findOne( { _id: targetUserId, "notifications._id": targetNotificationId }, { "notifications.$": 1, _id: 0 } ); const singleNotification = result?.notifications[0];
2. 更新单个通知元素
同样使用$位置操作符定位要更新的元素:
// 将指定通知的status改为read await this.userRepo.updateOne( { _id: targetUserId, "notifications._id": targetNotificationId }, { $set: { "notifications.$.status": "read" } } ); // 同时更新多个字段 await this.userRepo.updateOne( { _id: targetUserId, "notifications._id": targetNotificationId }, { $set: { "notifications.$.status": "read", "notifications.$.title": "已处理的网关白名单请求" } } );
3. 删除单个通知元素
使用$pull操作符移除数组中符合条件的元素:
// 删除指定_id的通知 await this.userRepo.updateOne( { _id: targetUserId }, { $pull: { notifications: { _id: targetNotificationId } } } ); // 删除所有状态为read的通知 await this.userRepo.updateOne( { _id: targetUserId }, { $pull: { notifications: { status: "read" } } } );
内容的提问来源于stack exchange,提问作者Andy95
相关产品推荐
相关产品推荐

