我有两个模式。PostSchema:
export type PostDocument = Post & Document;
@Schema({ collection: 'posts' })
export class Post {
@Prop()
description: string;
@Prop()
title: string;
// incorrect variant below
@Prop({
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
})
_id: ObjectId;
}
const PostSchema = SchemaFactory.createForClass(Post);
export { PostSchema as PostSchema };
和用户模式:
export type UserDocument = User & Document;
@Schema({
collection: 'users',
})
export class User {
@Prop()
name: string;
@Prop({
type: [
{ type: mongoose.Schema.Types.ObjectId, ref: 'Post', autopopulate: true },
],
})
posts: Post[];
}
const UserSchema = SchemaFactory.createForClass(User);
export { UserSchema as UserSchema };
但是我仍然不明白如何将第一个表与第二个表联系起来。在一个表中做所有事情要容易得多,但是我对这种方法很感兴趣。
1条答案
按热度按时间y1aodyip1#
首先,永远不要将Mongoose属性命名为
_id
。这是mongoose内部用来标识单个文档的字段名。在您的情况下,我建议将其命名为userId
或authorId
(根据代码上下文假定)。不过,在mongoose中定义一对多关系基本上有两种选择:
1.在Post方案中定义用户的ObjectId。
1.在用户架构中定义帖子的ObjectId数组。
基本上你已经做了这两个,这是可能的,但不是真正的最好的方法。这里的问题是,它是不容易保持两个独立的关系彼此同步(记住:您没有使用关系数据库,必须自己处理删除引用的工作)。
建议的方法:
在您的情况下,我建议您在Post模式中只定义用户的ObjectId(方法1),并在用户模式中创建一个名为“posts”的虚拟属性(如下所示:https://mongoosejs.com/docs/tutorials/virtuals.html#populate)。这样就可以轻松地从两个方向填充数据,而不必跟踪数据同步,因为关系仅在post Schema中定义。您应该解决的唯一问题是,如果删除了用户,则将此Post属性设置为null。在这种情况下,您应该定义一个挂钩。