簡體   English   中英

@nestjs/mongoose,虛擬填充 2 個數據庫

[英]@nestjs/mongoose, virtual populate with 2 databases

我正在嘗試從數據庫 2 中存在的用戶文檔填充數據庫 1 中存在的 userId 字段。

我已經在MongooseModule.ForRootAsync()中定義了connectionName參數,我找不到問題出在哪里。 如果我分別從db1db2請求信息,它也可以工作。

實際上在console.log(commentPopulated)上, userId字段只是 objectId,沒有來自 User 模式的填充字段,有時還帶有某些@Prop().populate()參數應用程序拋出這個錯誤:

MissingSchemaError: Schema hasn't been registered for model "User".

使用@nestjs/mongoose裝飾器我該如何實現?

app.module.ts

MongooseModule.forRootAsync({
  connectionName: 'db1',
  useFactory: () => ({
    uri: process.env.DB1,
    connectionFactory: (connection: { plugin: (arg0: unknown) => void }) => {
      connection.plugin(_)
      connection.plugin(autoPopulate)
      return connection
    },
  }),
}),
MongooseModule.forRootAsync({
  connectionName: 'db2',
  useFactory: () => ({
    uri: process.env.DB2,
    connectionFactory: (connection: { plugin: (arg0: unknown) => void }) => {
      connection.plugin(_)
      connection.plugin(autoPopulate)
      return connection
    },
  }),
}),

comment.module.ts

const commentModule: DynamicModule = MongooseModule.forFeatureAsync([
    {
        name: Comment.name,
        useFactory: () => {
            return CommentSchema
        }
    }
], 'db1')

@Module({
    imports: [commentModule],
    providers: [CommentService, CommentResolver]
})
export class CommentModule { }

comment.schema.ts

@Schema({ toJSON: { virtuals: true, getters: true }, toObject: { virtuals: true, getters: true } })
@ObjectType()
export class Comment extends Document {
    @Prop()
    @Field(() => String)
    readonly _id: MongooseSchema.Types.ObjectId

    @Prop({ required: true })
    @Field(() => String)
    text: string

    //TODO: Reference User document from DB2, Comment document exists in DB1
    @Prop({ type: MongooseSchema.Types.ObjectId, virtualpath: User.name, virtuals: true })
    @Field(() => User, { nullable: true })
    userId: MongooseSchema.Types.ObjectId

    @Prop({ type: String, enum: UserType, required: true, default: UserType.Regular })
    @Field(() => UserType, { defaultValue: UserType.Regular })
    userType: UserType

    @Prop({ default: Date.now })
    @Field(() => Date)
    created: Date
}

export const CommentSchema = SchemaFactory.createForClass(Comment)

user.module.ts

const userModule: DynamicModule = MongooseModule.forFeatureAsync([
  {
    name: User.name,
    useFactory: () => {
      return UserSchema
    },
  },
], 'db2')

@Module({
  imports: [userModule],
  providers: [UserService, UserResolver]
})
export class UserModule { }

user.schema.ts

@Schema()
@ObjectType()
export class User extends Document {
    @Prop()
    @Field(() => String)
    readonly _id: MongooseSchema.Types.ObjectId

    @Prop({ required: true })
    @Field(() => String)
    firstName: string

    @Prop({ required: true })
    @Field(() => String)
    lastName: string

    @Prop({ required: true })
    @Field(() => String)
    email: string
}

export const UserSchema = SchemaFactory.createForClass(User)

comment.service.ts

@Injectable()
export class CommentService {
    constructor(@InjectModel(Comment.name, 'db1') private readonly model: Model<Comment>) { }
    async getComments() {
        const commentPopulated = await this.model.findById('63b8608c7d4f880cba028bfe').populate('userId')
        console.log(commentPopulated)
        return commentPopulated
    }
}

我曾嘗試在@Prop()裝飾器上隨機播放參數但沒有成功,我認為存在問題,還播放了.populate() function 參數。

const db1 = mongoose.createConnection('mongodb://127.0.0.1:27000/db1');
const db2 = mongoose.createConnection('mongodb://127.0.0.1:27001/db2');

const userSchema = new Schema({...});
const User= db2.model('User', userSchema);

const commentSchema = new Schema({
...
user: {
type: ObjectId,
ref: User // `ref` is a **Model class**, not a string
}
});
const Comment = db1.model('Comment', commentSchema);

const comments = await Comment.
find().
populate('user');

這個例子來自mongoose docs Cross Database Populate

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM