diff --git a/server/service/review.service.ts b/server/service/review.service.ts index c19b8a2..833445b 100644 --- a/server/service/review.service.ts +++ b/server/service/review.service.ts @@ -1,7 +1,6 @@ -import { In, Repository } from 'typeorm' +import { Repository } from 'typeorm' import { Inject, InjectRepository, Service } from '../provider' import { UserClubReviewEntity } from '../infra/database/entities/user-club-review.entity' -import { ClubReviewKeywordEntity } from '../infra/database/entities/club-review-keyword.entity' import { ClubReviewKeywordCategoryEntity } from '../infra/database/entities/user-club-review-category.entity' import { ReviewKeywordCategory } from '../../src/lib/schemas/common' import { ClubRanking, MyReview } from '../../src/lib/schemas/clubs' @@ -9,8 +8,6 @@ import { ClubAccessService } from './club-access.service' @Service export class ReviewService { - @InjectRepository(ClubReviewKeywordEntity) - private readonly clubReviewKeywordRepository: Repository @InjectRepository(ClubReviewKeywordCategoryEntity) private readonly clubReviewKeywordCategoryRepository: Repository @InjectRepository(UserClubReviewEntity) @@ -89,56 +86,22 @@ export class ReviewService { public async getClubRankings(topk = 5): Promise { const aggregated: { club_id: string - total_reviews: string - rating: string club_name: string - club_full_name: string + category: string }[] = await this.userClubReviewRepository.query(` -SELECT ucr.club_id, COUNT(ucr.id) AS total_reviews, COALESCE(AVG(ucr.rating), 0) AS rating, MAX(c.name) AS club_name, MAX(c.full_name) AS club_full_name +SELECT ucr.club_id, MAX(c.name) AS club_name, MAX(c.category) AS category FROM user_club_review ucr JOIN club c ON ucr.club_id = c.uuid AND c.deleted_at IS NULL AND c.status = 'APPROVED' -GROUP BY club_id +GROUP BY ucr.club_id ORDER BY COUNT(*) DESC LIMIT ${topk} `) - if (!aggregated.length) { - return [] - } - const reviews = await this.userClubReviewRepository.findBy({ - clubId: In(aggregated.map((it) => it.club_id)), - }) - return Promise.all( - aggregated.map(async (it, idx) => { - const totalKeywords = reviews - .filter((r) => it.club_id === r.clubId) - .flatMap((r) => r.reviewKeywordIds) - const keywordIds = this.mostFrequent(totalKeywords, 3) - const keyword = await this.clubReviewKeywordRepository.findBy({ id: In(keywordIds) }) - const keywordTitles = keywordIds - .map((it) => keyword.find((k) => k.id === it)?.title ?? '') - .filter((it) => it) - return { - clubId: it.club_id, - clubName: it.club_name, - clubFullName: it.club_full_name, - totalReviews: Number(it.total_reviews), - rating: Number(it.rating), - ranking: idx + 1, - keywords: keywordTitles, - } - }), - ) - } - private mostFrequent(input: string[], topN = 3): string[] { - const frequencyMap = input.reduce((acc, cur) => { - acc[cur] = (acc[cur] ?? 0) + 1 - return acc - }, {} as { [key: string]: number }) - return Array.from(new Set(input)) - .map((key): [string, number] => [key, frequencyMap[key]]) - .sort((a, b) => b[1] - a[1]) - .slice(0, topN) - .map((it) => it[0]) + return aggregated.map((it, idx) => ({ + clubId: it.club_id, + clubName: it.club_name, + category: it.category, + ranking: idx + 1, + })) } } diff --git a/src/lib/schemas/clubs.ts b/src/lib/schemas/clubs.ts index a5a22b6..df92ea5 100644 --- a/src/lib/schemas/clubs.ts +++ b/src/lib/schemas/clubs.ts @@ -63,10 +63,7 @@ export const ClubRankingSchema = z ranking: z.number().int(), clubId: z.string().uuid(), clubName: z.string(), - clubFullName: z.string(), - totalReviews: z.number().int(), - rating: z.number(), - keywords: z.array(z.string()), + category: z.string(), }) .openapi('ClubRanking')