如何基于关联值过滤NestJS Repository的查询结果?
解决NestJS+TypeORM中获取未关联Warehouse的Address数据问题
先修正实体定义的错误
你的Address实体中warehouse字段的类型定义有误,应该关联到Warehouse实体而非string | null,TypeORM需要正确的实体类型来处理关联关系:
@Entity() export class Address { [key: string]: string | string[] | number | Record<string, unknown> | Date; @PrimaryGeneratedColumn({ type: "bigint", name: "address_id", }) id: string; @Column({ nullable: true, }) customerId?: string; @Field() @OneToOne(() => Warehouse, (warehouse: Warehouse) => warehouse.address, { nullable: true }) // 修正类型为Warehouse | null warehouse?: Warehouse | null; }
使用Repository实现过滤逻辑
由于外键字段address_id存在于Warehouse表中(因为Warehouse加了@JoinColumn),直接通过warehouse: null或IsNull()过滤会失效,需要通过子查询检查是否存在关联的Warehouse记录来实现。
使用TypeORM的Not和Exists操作符,结合Repository的find方法完成查询:
import { Not, Exists, Repository } from 'typeorm'; import { Injectable } from '@nestjs/common'; import { Address } from './entities/address.entity'; @Injectable() export class AddressesService { constructor( @InjectRepository(Address) private addressRepository: Repository<Address>, ) {} findAllAddresses() { return this.addressRepository.find({ where: { id: Not(Exists( this.addressRepository.createQueryBuilder('warehouse') .select('1') .where('warehouse.address_id = address.address_id') )) }, // 无需关联warehouse,我们要找的是未关联的地址,加载关联只会增加不必要开销 }); } }
逻辑说明
- 通过
Exists子查询检查当前Address的id是否在Warehouse表的address_id字段中存在 - 用
Not取反,得到所有不存在对应Warehouse记录的Address数据
为什么之前的方法失效?
- 直接写
warehouse: null时,TypeORM无法正确解析关联字段的空值过滤,因为Address表本身没有存储Warehouse的外键,外键在Warehouse表中 - 使用
IsNull()时,TypeORM会尝试在Address表中找对应的字段,但该字段不存在,因此抛出This relation isn't supported by given find operator错误
内容的提问来源于stack exchange,提问作者m3.b
相关产品推荐
相关产品推荐

