NestJS和Mongoose通过引用对象Id查找

Inn*_*ve1 17 mongoose typescript nestjs

我有 Mongo 用户集合和地址集合。每个地址都由一个用户拥有。这是我的架构类:


export type UserDocument = User & mongoose.Document
@Schema({ timestamps: true })
export class User {
  // @Prop({ type: mongoose.Types.ObjectId })
  _id: string

  @Prop({ required: true })
  name: string

  @Prop({ required: true, unique: true })
  email: string

  @Prop({ select: false })
  password: string

}
export const UserSchema = SchemaFactory.createForClass(User)

export type AddressDocument = Address & Document
@Schema({ timestamps: true })
export class Address {
  @Prop({ type: mongoose.Schema.Types.ObjectId, ref: User.name })
  user: User

  @Prop()
  line1: string

  @Prop()
  line2?: string

  @Prop()
  city: string

  @Prop()
  state?: string

  @Prop()
  country: string
}

export const AddressSchema = SchemaFactory.createForClass(Address)
Run Code Online (Sandbox Code Playgroud)

然后我有一个 AddressService 可以获取用户的地址:

@Injectable()
export class AddressService {
  constructor(@InjectModel(Address.name) private addressModel: Model<AddressDocument>) {}

  async save(address: AddressDto): Promise<Address> {
    const model = await this.addressModel.create(address)
    return model.save()
  }

  async findAddressForUser(userId: string) {
    const userObjectId = new mongoose.Types.ObjectId(userId)
    const users = await this.addressModel.find({ user: userObjectId })
  }
}
Run Code Online (Sandbox Code Playgroud)

这段代码有一个错误:Type '_ObjectId' is not assignable to type 'Condition<User> 我也尝试将 userId 作为字符串传递,但这也不起作用。

使用另一个集合中的引用 ID 查询集合的正确方法是什么?

EzP*_*zza 18

我认为该user字段不应该是 type User,不管 NestJS 文档怎么说。应该是 类型的Types.ObjectId

像这样的东西(也有更清洁的进口):

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { SchemaTypes, Types, Document } from 'mongoose';

export type AddressDocument = Address & Document
@Schema({ timestamps: true })
export class Address {
  @Prop({ type: SchemaTypes.ObjectId, ref: User.name })
  user: Types.ObjectId;

  ...

}
export const UserSchema = SchemaFactory.createForClass(User)
Run Code Online (Sandbox Code Playgroud)

我从这里得到这个。

您还可以通过将其声明为以下方式来告诉 TypeScript 这可能是一个字符串、一个 ObjectId 或一个用户:user: string | Types.ObjectId | UserDocument;


Inn*_*ve1 8

不确定这是否是执行此操作的正确方法,但这就是我最终为解决该错误所做的事情:

  async findAddressForUser(userId: string): Promise<Address[]> {
    const query: any = { user: new mongoose.Types.ObjectId(userId) }
    return await this.addressModel.find(query).exec()
  }
Run Code Online (Sandbox Code Playgroud)