我正在使用 NestJS 和 Mongoose 开发应用程序,并且在包含 ObjectId 数组的架构中使用 populate() 方法时遇到问题。当字段是单个 ObjectId 时,该方法可以正常工作,但当字段是 ObjectId 数组时,该方法无法正确填充。
模型和架构
以下是用户和卡的 Mongoose 模式:
User Schema
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Types, Document } from 'mongoose';
@Schema()
export class UserClass {
@Prop({ required: true, unique: true })
username: string;
@Prop({ type: [{ type: Types.ObjectId, ref: 'Card' }] })
cards: Types.ObjectId[];
}
export const UserEntity = SchemaFactory.createForClass(UserClass);
Card Schema
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
@Schema()
export class CardClass {
@Prop({ required: true, unique: true })
token: string;
// Additional properties
}
export const CardEntity = SchemaFactory.createForClass(CardClass);
存储库方法 这是我的存储库中尝试使用 populate() 的方法:
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User, UserDocument } from './user.entity';
@Injectable()
export class UsersRepository {
constructor(@InjectModel(User.name) private userModel: Model<UserDocument>) {}
async findUserWithCardsById(userId: string): Promise<UserDocument | null> {
return this.userModel
.findOne({ _id: userId })
.populate('cards')
.exec();
}
}
问题:
执行 findUserWithCardsById 方法时,应使用与用户的卡片数组中存储的 ID 对应的卡片文档填充卡片字段。但是,该数组返回未填充的内容,尽管当卡片字段是单个 ObjectId(非数组)时它确实有效。
额外的背景信息 有趣的是,当我将用户模式中的卡片字段从数组修改为单个 ObjectId 时:
@Prop({ type: Types.ObjectId, ref: 'Card' })
cards: Types.ObjectId;
populate() 函数运行完美,返回预期的卡片属性。这确认了集合和模型已正确连接和引用,因为当卡片配置为单个 ObjectId 时,总体会正确执行。这表明该问题特定于处理 ObjectId 数组。
问题 如何解决此问题,以便 populate() 在带有 Mongoose 的 NestJS 中的 ObjectId 数组中正确运行?我需要实施任何其他配置或步骤才能正确处理引用数组吗?
致谢 我将不胜感激有关如何解决此问题的任何帮助或指导,因为这对于我的应用程序的功能至关重要。
预期行为 当将 Mongoose 的 populate() 方法与用户模式中的 ObjectId 数组一起使用时,我希望卡片数组中的每个 ObjectId 都应使用数据库中相应的卡片文档进行填充。这应该会导致用户文档中的卡片数组包含每个引用的完整卡片文档详细信息,而不仅仅是 ObjectId。
这是我期望发生的事情的代码片段:
// Repository method expected to populate user's cards
async findUserWithCardsById(userId: string): Promise<UserDocument | null> {
return this.userModel
.findOne({ _id: userId })
.populate({
path: 'cards',
select: 'token subtoken franchise lastDigits validUntil' // Expected fields to be populated from Card
})
.exec();
}
// Expected result structure
{
_id: userId,
username: 'johndoe',
cards: [
{
_id: cardId,
token: 'someToken',
subtoken: 'someSubtoken',
franchise: 'someFranchise',
lastDigits: '1234',
validUntil: '12/2030'
},
// Additional cards populated similarly
]
}
这种结构化结果就是我想要实现的目标,其中每张卡的详细信息都被检索并显示为用户文档的一部分。当卡片是单个 ObjectId 时,此功能按预期工作,但当卡片是 ObjectId 数组时,则无法按预期工作,尽管集合和模型已正确连接和引用。
ref 选项告诉 Mongoose 在填充过程中使用哪个模型。
就您而言,您的参考号是卡:
@Prop({ type: [{ type: Types.ObjectId, ref: 'Card' }] })
cards: Types.ObjectId[];
而您的型号名称可能是 CardClass。
您可以决定是否将引用从Card重命名为您注册的名称(我假设是CardClass)。 在模型中注册不同的名称也应该有效:
@Module({
imports: [
MongooseModule.forFeature([
{ name: 'Card', schema: CardEntity },
//...
]),
],
controllers: [], // Add your controllers
providers: [], // your pr
})
export class AnyModule {}