我有这样的实体:
@Entity('user')
export class User {
@PrimaryGeneratedColumn('uuid')
id: string;
@ManyToMany(() => Product, { onDelete: 'NO ACTION', onUpdate: 'CASCADE' })
@JoinTable({
name: 'user-products',
joinColumn: { name: 'userId', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'productId', referencedColumnName: 'id' },
})
products?: Product[];
}
和
@Entity({ name: 'product' })
@Unique(['name'])
export class Product {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ type: 'varchar' })
name: string;
@ManyToMany(() => User, user => user.products, { onDelete: 'NO ACTION', onUpdate: 'CASCADE' })
users?: User[];
}
和
@Entity('user-products')
export class UserProducts {
@PrimaryColumn('uuid', { name: 'userId' })
userId: string;
@PrimaryColumn('uuid', { name: 'productId' })
productId: string;
@ManyToOne(() => User, user => user.products, { onDelete: 'NO ACTION', onUpdate: 'CASCADE' })
@JoinColumn([{ name: 'userId', referencedColumnName: 'id' }])
users: User[];
@ManyToOne(() => Product /*, product => product.users*/, { onDelete: 'NO ACTION', onUpdate: 'CASCADE' })
@JoinColumn([{ name: 'productId', referencedColumnName: 'id' }])
products: Product[];
}
当我查询数据库时,我这样做:
this.myRepo
.createQueryBuilder('user')
.leftJoinAndSelect('user.products', 'userProducts')
到目前为止一切进展顺利。但是当我添加搜索查询时,例如:
this.userRepo
.createQueryBuilder('user')
.leftJoinAndSelect('user.products', 'userProducts')
.where(`userProducts.name ilike '%${mySearchValue}%'`)
我仍然得到正确的结果,但如果用户有多个产品,它只会返回具有该特定产品的用户,并且我希望返回结果中仍然包含所有产品。举例来说,假设我有 3 个用户
{
"id": "user_1_id",
"products": [
{
"id": "product_1_id",
"name": "product_1",
},
{
"id": "product_2_id",
"name": "product_2",
},
{
"id": "product_3_id",
"name": "product_3",
},
],
},
{
"id": "user_2_id",
"products": [
{
"id": "product_2_id",
"name": "product_2",
},
{
"id": "product_3_id",
"name": "product_3",
},
{
"id": "product_4_id",
"name": "product_4",
},
],
},
{
"id": "user_3_id",
"products": [
{
"id": "product_5_id",
"name": "product_5",
},
{
"id": "product_6_id",
"name": "product_6",
}
],
}
我搜索product_2。结果会是
{
"id": "user_1_id",
"products": [
{
"id": "product_2_id",
"name": "product_2",
},
],
},
{
"id": "user_2_id",
"products": [
{
"id": "product_2_id",
"name": "product_2",
},
],
}
但我希望它是:
{
"id": "user_1_id",
"products": [
{
"id": "product_1_id",
"name": "product_1",
},
{
"id": "product_2_id",
"name": "product_2",
},
{
"id": "product_3_id",
"name": "product_3",
},
],
},
{
"id": "user_2_id",
"products": [
{
"id": "product_2_id",
"name": "product_2",
},
{
"id": "product_3_id",
"name": "product_3",
},
{
"id": "product_4_id",
"name": "product_4",
},
],
}
有点像过滤器方法的运行。有没有办法实现这个目标?
如果有人遇到过这个,我找到了答案,这让我伤透了脑筋。这是:
const result: SelectQueryBuilder<User> = this.userRepo
.createQueryBuilder('user')
.leftJoinAndSelect('user.products', 'userProducts')
.where((qb: SelectQueryBuilder<User>) => {
const productSubQuery = qb
.subQuery()
.select('user-products.userId')
.from('user-products', 'user-products')
.leftJoin('product', 'p', 'p.id = user-products.productId')
.where('p.name ILIKE :productName', { productName: `%${mySearchValue}%`})
.getQuery();
return `user.id IN ${productSubQuery}`;
});
const final: User[] = await result.getMany();