在NestJS中使用Mongoose更新带关联条件的Mongo集合失败
NestJS中Mongoose更新MongoDB文档未生效问题
问题描述
在NestJS中使用Mongoose操作MongoDB,完成账单金额计算后,尝试将符合条件的Event文档的billed字段更新为true,但更新操作无报错却未生效。
相关代码定义
Interfaces
export interface ISubscription { name: string; category: string; .... } export interface IPlan { name: string; status: string; charges?: [ICharge]; } export interface IEvent { subscription: ISubscription; plan: IPlan; date: Date; type: string; amount: number; data: any; billed: boolean; }
Subscription Schema
interface SubscriptionDocument extends ISubscription, Document {} const SubscriptionSchemaFields: Record<keyof ISubscription, any> = { name: String, category: String, ........ }; const SubscriptionSchema = new Schema(SubscriptionSchemaFields); const Subscription = model<SubscriptionDocument>( 'Subscription', SubscriptionSchema, ); export { SubscriptionDocument, SubscriptionSchema, Subscription };
Event Schema Definition
interface EventDocument extends IEvent, Document {} const EventSchemaFields: Record<keyof IEvent, any> = { subscription: { type: Schema.Types.ObjectId, ref: 'Subscription', }, plan: { type: Schema.Types.ObjectId, ref: 'Plan', }, date: Date, type: String, amount: Number, data: Object, billed: { type: Boolean, default: false, }, }; const EventSchema = new Schema(EventSchemaFields); const Event = model<EventDocument>('Event', EventSchema); export { EventDocument, EventSchema, Event };
账单计算与更新操作
账单金额聚合查询
const balanceCalc = await this.eventModel.aggregate([ { $match: { subscription: { $eq: Types.ObjectId(instantBill.subscription) }, plan: { $eq: Types.ObjectId(instantBill.plan) }, billed: { $eq: false }, }, }, { $group: { _id: null, sumamount: { $sum: '$amount' }, }, }, ]);
未生效的更新代码
const eventupdate = await this.eventModel.updateMany( { 'subscription._id': subscriptionId, 'plan._id': planId, billed: false, }, { $set: { billed: true } }, );
其中subscriptionId和planId均为字符串,预期匹配对应subscription和plan的未账单化Event并更新,但操作无报错却未生效。
解决方案
问题出在更新条件的写法和ID类型不匹配:
- 字段路径错误:Event Schema中
subscription和plan是直接存储的ObjectId类型,不是嵌套对象,因此'subscription._id'这种嵌套路径写法无法匹配到文档。 - ID类型不匹配:数据库中存储的是
ObjectId类型,而传入的subscriptionId和planId是字符串,需要转换为Mongoose的ObjectId才能匹配。
修正后的更新代码如下:
import { Types } from 'mongoose'; // 转换字符串ID为ObjectId const subId = Types.ObjectId(subscriptionId); const pId = Types.ObjectId(planId); const eventupdate = await this.eventModel.updateMany( { subscription: subId, plan: pId, billed: false, }, { $set: { billed: true } }, );
可以参考聚合查询中的条件写法,保持一致的匹配逻辑,避免出现路径或类型错误。
内容的提问来源于stack exchange,提问作者Mujibur Rahman
相关产品推荐
相关产品推荐

