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
我有两个具有多对多关系的实体图片和标签
@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