Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 태그 검색 구현 #71

Merged
merged 6 commits into from
Jun 7, 2024
Merged

feat: 태그 검색 구현 #71

merged 6 commits into from
Jun 7, 2024

Conversation

wugawuga
Copy link
Contributor

@wugawuga wugawuga commented Jun 2, 2024

  • 상품의 태그 Top3 중 있으면 검색해서 조회

Issue

✨ 구현한 기능

  • 상품들이 가지고 있는 리뷰중에서 Top3 태그로만 검색이 되게 구현했습니다.

- 상품의 태그 Top3 중 있으면 검색해서 조회
@wugawuga wugawuga requested review from Go-Jaecheol and 70825 June 2, 2024 04:47
@wugawuga wugawuga self-assigned this Jun 2, 2024
Copy link

github-actions bot commented Jun 2, 2024

Test Results

330 tests  +15   330 ✅ +15   19s ⏱️ -1s
203 suites + 9     0 💤 ± 0 
203 files   + 9     0 ❌ ± 0 

Results for commit a76f820. ± Comparison against base commit 8c7870f.

♻️ This comment has been updated with latest results.

Copy link
Member

@70825 70825 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우가 고생하셨어요~
쿼리문에 궁금한 점이 있어서 코멘트 남깁니다~

1. 상품의 태그 Top3 중 있으면 검색해서 조회

상품의 태그 TOP 3이라는 뜻은 상품에서 가장 많이 언급된 태그 3개를 말하는거죠??

제가 이해하는게 맞다면 아래 테스트 코드는 통과하지 말아야 하는데 통과하고 있어요

product1에 달린 태그
단짠단짠: 3회
맛있어요: 3회
갓성비: 2회
간식: 1회
        @Test
        void 간식_태그는_4위이므로_검색되지_말아야한다() {
            // given
            final var category = 카테고리_간편식사_생성();
            단일_카테고리_저장(category);

            final var 태그_맛있어요 = 태그_맛있어요_TASTE_생성();
            final var 태그_단짠단짠 = 태그_맛있어요_TASTE_생성();
            final var 태그_갓성비 = 태그_맛있어요_TASTE_생성();
            final var 태그_간식 = 태그_간식_ETC_생성();

            final var 태그1 = 단일_태그_저장(태그_맛있어요);
            final var 태그2 = 단일_태그_저장(태그_단짠단짠);
            final var 태그3 = 단일_태그_저장(태그_갓성비);
            final var 태그4 = 단일_태그_저장(태그_간식);

            final var product1 = 상품_애플망고_가격3000원_평점5점_생성(category);
            final var product2 = 상품_망고빙수_가격5000원_평점4점_생성(category);
            final var product3 = 상품_망고빙수_가격5000원_평점4점_생성(category);
            final var product4 = 상품_망고빙수_가격5000원_평점4점_생성(category);
            복수_상품_저장(product1, product2, product3, product4);

            final var member1 = 멤버_멤버1_생성();
            final var member2 = 멤버_멤버2_생성();
            복수_멤버_저장(member1, member2);

            final var review1_1 = 리뷰_이미지test1_평점1점_재구매X_생성(member1, product1, 0L);
            final var review1_2 = 리뷰_이미지test5_평점5점_재구매O_생성(member2, product1, 0L);
            final var review2_1 = 리뷰_이미지test3_평점3점_재구매O_생성(member1, product2, 0L);
            복수_리뷰_저장(review1_1, review1_2, review2_1);

            복수_리뷰_태그_저장(
                    리뷰태그_생성(review1_1, 태그_맛있어요),
                    리뷰태그_생성(review1_1, 태그_맛있어요),
                    리뷰태그_생성(review1_1, 태그_단짠단짠),
                    리뷰태그_생성(review1_1, 태그_단짠단짠),
                    리뷰태그_생성(review1_1, 태그_갓성비),
                    리뷰태그_생성(review1_1, 태그_갓성비),
                    리뷰태그_생성(review1_1, 태그_간식),
                    리뷰태그_생성(review1_1, 태그_맛있어요),
                    리뷰태그_생성(review1_2, 태그_단짠단짠),
                    리뷰태그_생성(review2_1, 태그_맛있어요)
            );

            final var expected = List.of(product1);

            // when
            final var actual = productRepository.searchProductsByTopTagsFirst(태그4, PageRequest.of(0, 10));

            // then
            assertThat(actual).usingRecursiveComparison()
                    .isEqualTo(expected);
        }

2. 쿼리문에서 궁금한 점

searchProductsByTopTagsFirst 쿼리문입니다

                "   WHERE rt2.tag.id = :tagId AND rt2.tag.id IN ( " +
                "       SELECT rt3.tag.id FROM Review r3 " +
                "       JOIN r3.reviewTags rt3 " +
                "       WHERE r3.product.id = p2.id " +
                "       GROUP BY rt3.tag.id " +
                "       ORDER BY COUNT(rt3.tag.id) DESC " +
                "   ) " +
  1. 위 서브쿼리문은 상품에 검색한 태그가 있어야 한다는거죠?? 이게 맞으면 상품에 적용된 상위 3개 태그를 확인하는게 맞는 것 같은데 LIMIT 3이 언급되는 부분이 없어서요. 거기다가 LIMIT 3이 없으면 ORDER BY COUNT(rt3.tag.id) DESC는 필요 없는 쿼리문으로 보여요
                "   WHERE rt2.tag.id = :tagId AND rt2.tag.id IN ( .... )" +
                "   GROUP BY p2.id " +
                "   HAVING COUNT(DISTINCT rt2.tag.id) <= 3 " +
  1. 위 쿼리문에서 HAVING COUNT(DISTINCT rt2.tag.id) <= 3특정 태그는 3개 이하여야 한다라는 쿼리문인데, 의미 없는 쿼리문으로 보여서요.
    왜냐하면 WHERE rt2.tag.id = :tagId로 인해서 tagId인 태그만 감지되는 상황이라 (상품1, 리뷰1, 태그1), (상품1, 리뷰2, 태그1), (상품1, 리뷰3, 태그1), ...로 태그1을 포함하는 데이터들만 나오게 되는데요. 이때 DISTINCT rt2.tag.idrt2.tag.id 적용 -> (태그1), (태그1), (태그1), ... -> DISTINCT 적용 -> (태그1)로 데이터 1개만 나오기 때문에 HAVING COUNT(DISTINCT rt2.tag.id) <= 3은 곧 1 <= 3이라서 무조건 참인 쿼리문이라서요.

제가 이해한게 맞다면 쿼리문 자체를 다시 수정해야 할 것 같습니다

Copy link
Member

@70825 70825 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우가 고생하셨어요
쿼리문에 """로 하니까 확실히 보기 편하네요 👍👍
간단한 부분 수정하고 머지하면 될 것 같아서 미리 Approve 하겠습니다 ~

@wugawuga wugawuga requested a review from 70825 June 6, 2024 01:49
Copy link
Member

@70825 70825 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍👍

Copy link
Contributor

@Go-Jaecheol Go-Jaecheol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍

@Go-Jaecheol Go-Jaecheol merged commit 9324373 into develop Jun 7, 2024
3 checks passed
@Go-Jaecheol Go-Jaecheol deleted the feat/issue-60 branch June 7, 2024 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

태그 검색
3 participants