Nestjs typeorm 多对多按计数排序

Nestjs typeorm many to many order by count

我有两个具有多对多关系的实体图片和标签

@Entity()
export class Image {
  @PrimaryGeneratedColumn()
  id: number;

  @Column('text', { nullable: true })
  caption: string;

  @Column('text', { nullable: false })
  url: string;

  @Column('text', { nullable: false })
  thumbnailUrl: string;

  @ManyToOne(() => User, {
    eager: true,
  })
  uploader: User;

  @JoinTable()
  @ManyToMany(() => Tag, (tag: Tag) => tag.images, {
    cascade: true,
    eager: true,
  })
  tags?: Tag[];

  @CreateDateColumn()
  created_at: Date;

  @UpdateDateColumn()
  updated_at: Date;

和标签实体

@Entity()
export class Tag {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @ManyToMany(() => Image, (image) => image.tags)
  images: Image[];
}

现在我想获取热门标签。为此,取 10 个在过去 7 天内创建的图像数量最多的标签。为此,我尝试关注 tag.repository.ts

getPopular() {
    return (
      this.createQueryBuilder('tag')
        .addSelect((query) => {
          return query
          .select('COUNT(I.id)', 'count')
          .from('image', 'I')
          .where('I.created_at > :date', {
            date: DateTime.now().minus({ weeks: 1 }).toISODate(),
          });
        }, 'imagecount')
        .orderBy('imagecount', 'DESC')
        .take(10)
        .getMany()
    );

但是这将计算过去 7 天内创建的所有图像,并且不会考虑图像是否具有该标签。那么我应该如何加载关系以便它计算带有标签的图像?

我建议您稍微改变一下您的方法,并尝试在按过去 7 天过滤后进行分组。此外,除非您有明确的情况要将图像添加到标签中,否则我建议您在 Tag 实体中删除 images 属性 因为您已经有办法将标签与图像相关联。

  this.repository
  .createQueryBuilder('image')
  .where('image.created_at > :created_at', {
    created_at: '2022-01-14 01:02:26', // make sure you set your own date here
  })
  .leftJoinAndSelect('image.tags', 'tag')
  .groupBy('tag.id') // here is where we grup by the tag so we can count
  .addGroupBy('tag.id')
  .select('tag.id, count(tag.id)') // here is where we count :)
  .orderBy('count(tag.id)', 'DESC')
  .limit(10) // here is the limit
  .execute();

这两套文档可以帮助您更好地理解这个查询是如何构建的。

https://orkhan.gitbook.io/typeorm/docs/many-to-many-relations

https://github.com/typeorm/typeorm/blob/master/docs/select-query-builder.md#adding-group-by-expression