使用 TypeORM 进行搜索可以部分工作,但不会返回所有关系

问题描述 投票:0回答:1

我有这样的实体:

@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",
      },
   ],
}

有点像过滤器方法的运行。有没有办法实现这个目标?

postgresql search filter typeorm
1个回答
0
投票

如果有人遇到过这个,我找到了答案,这让我伤透了脑筋。这是:

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();
© www.soinside.com 2019 - 2024. All rights reserved.