ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20230111 TIL 될 때까지 방법을 찾아보기
    TIL 2023. 1. 11. 17:54

     

    포트폴리오에서 이용자 검색 기능을 구현하는 과정에서 이때까지 만난 것 중 가장 복잡한 수준의 쿼리를 만나게 되었다.

    사용자가 받은 추천 수를 기준으로 정렬을 하고 싶었는데,

    질문에서 받은 추천 수가 있을 수도 있고, 답변에서 받은 추천 수도 있을 텐데,

    질문에서 받은 추천 수와 답변에서 받은 추천 수를 합친 추천 수를 기준으로 정렬을 하고자 하였다.

     

    그래서 처음에는 아래와 같은 방식을 이용하려고 하였다.

    @Formula("(SELECT SUM(count) " +
            "FROM " +
            "((SELECT COUNT(*) count " +
            "FROM answer_like_user_ids al " +
            "JOIN answer a " +
            "ON al.answer_id = a.id " +
            "WHERE a.author_id = id) " +
            "UNION ALL " +
            "(SELECT COUNT(*) count " +
            "FROM question_like_user_ids ql " +
            "JOIN question q " +
            "ON ql.question_id = q.id " +
            "WHERE q.author_id = id" +
            ")))")

    그런데 유효하지 않다고 빌드가 되지 않았다.

    그 이유는 바로 subquery에서 사용한 WHERE에 들어있는 id칼럼 값을 참조할 수 없기 때문이었다.

     

    @Formula("(SELECT COUNT(*) " +
            "FROM " +
            "(SELECT a.author_id " +
            "FROM answer_like_user_ids al " +
            "JOIN answer a " +
            "ON al.answer_id = a.id " +
            "UNION ALL " +
            "SELECT q.author_id " +
            "FROM question_like_user_ids ql " +
            "JOIN question q " +
            "ON ql.question_id = q.id " +
            ") AS results WHERE results.author_id = id)")

    이렇게도 시도를 해보았는데, results라는 alias를 만드는 게 아닌 엔티티 필드 값으로 인식을 해버려서 이 방식도 실패하였다.

     

    여러가지 방법을 시도해본 끝에 아래 방식으로 질문 추천 수와 답변 추천 수의 합에 해당하는 필드를 만들 수 있게 되었다.

    @Formula("(SELECT COUNT(*) " +
            "FROM question_like_user_ids ql " +
            "JOIN question q " +
            "ON ql.question_id = q.id " +
            "WHERE q.author_id = id" +
            ") " +
            "+ " +
            "(SELECT COUNT(*) " +
            "FROM answer_like_user_ids al " +
            "JOIN answer a " +
            "ON al.answer_id = a.id " +
            "WHERE a.author_id = id" +
            ")")

     

    그리고 오늘 약 5시간에 걸쳐 또 하나의 조회 관련 코드를 작성하였는데,

    바로 사용자가 자신이 자신있는 분야에 해당하는 태그들이 있는데,

    그 태그를 검색했을 때 사용자가 검색되게끔 하는 기능과 관련된 코드였다.

     

    elementCollection 값 중에 like로 비교해서 있는지를 확인해야 했고,

    specification을 이용했고, 아래와 같이 join을 이용해서 아래와 같이 작성할 수 있었다.

    criteriaBuilder.like(criteriaBuilder.upper(root.join("tags", JoinType.LEFT).get("value")), "%" + keyword.toUpperCase() + "%"),

    그런데 JoinType.LEFT가 없으면 만약 tags가 null이나 empty이면 exception이 발생하기 때문에 꼭 넣어줘야 한다.

     

    해결되지 않을 것 같았는데 그래도 어떻게든 완료를 하여서 기뻤다.

    남은 기간동안 조금 더 힘내보자.

    댓글

Designed by Tistory.