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(Problem): 문제 상세 조회 API, 유사 문제 조회 API 구현 #62

Merged
merged 15 commits into from
Sep 3, 2024

Conversation

morenow98
Copy link
Member

PR 변경된 내용

문제 상세 조회 API

  • 관련 QueryDSL 쿼리 추가

유사 문제 조회 API

  • AWS OpenSearch 사용

  • OpenSearch 구성 완료

    • OpenSearch 에는 문제의 특성 벡터들 존재. 해당 벡터들은 GPT로 임베딩한 결과
    • 정확성이 떨어지는 상태이므로 벡터값은 추후 변경 예정
    • 벡터값의 코사인 유사도를 계산해 가까운 벡터일수록 유사하다고 판단
  • SimilarProblemsProvider 클래스를 통해 AWS와 통신

    1. 캐시에 검색 대상 문제의 유사 문제 목록이 있는지 확인
    2. 없으면 OpenSearch와 통신해서 "검색 대상 문제 벡터 조회"와 "유사 문제 조회"를 실시하고, 결과를 캐시에 저장함. 이 때 자격증마다 다른 인덱스를 가지도록 함. (OpenSearch에서 인덱스는 데이터베이스에 대응되는 개념)
    • 검색 대상 문제 벡터 조회
      검색 대상 문제의 벡터값을 가져옴. 이 때, 유사 문제 검색 메소드의 벡터 입력값이 float[]이므로 벡터값을 가져와서 float[] 으로 변환.
      • stream 등을 통해 float[]로 변환하는 메소드가 존재하지 않음. int[], long[], double[] 만 존재. 따라서 아래와 같이 변환
      //Float[] -> float[] 변환
      float[] vector = new float[problemVector.size()];
      IntStream.range(0, problemVector.size()).forEach(i -> vector[i] = problemVector.get(i));
    • 유사 문제 조회
      검색 대상 문제 벡터값을 사용해 유사 문제 ID를 조회. 이 때 쿼리를 날리면 유사도가 가장 높은 문제는 자기 자신이므로, (가져올 문제 개수 + 1)만큼에 대한 쿼리를 날리고 첫 번째 원소는 스킵하도록 구현
      // 검색 결과에서 유사 문제 ID 추출
      return searchResponse.hits().hits().stream()
              .map(Hit::id)
              .map(Long::parseLong)
              .skip(1) // 첫 번쨰 원소는 원래 문제 자체이므로 스킵
              .limit(KNN_K)
              .toList();  

추가 내용

  • 단순한 문자 연결을 StringBuilder에서 String으로 변경
  • 로그 레벨 다수 변경 (개발자가 의도한 오류를 INFO레벨로 변경)
  • dto 이름 변경

참조

Closes #60

- jdk1.5부터 단순한 문자열의 연결 연산은 컴파일될 때 내부적으로 StringBuilder로 변환된다.
- 따라서 Loop를 제외한 단순한 문자열 연결은 StringBuilder를 굳이 사용하지 않아도 된다.
- https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000093250-Convert-StringBuilder-to-String-concatenation-suggestion
- 개발자가 의도한 400 등의 에러는 info 레벨로 조정
- 의도하지 않은 Exception은 error 레벨로 유지
- AWS opensearch를 활용
- 관련 의존성 및 환경 변수 추가
- SimilarProblemId는 Redis를 활용한 캐싱 처리
@morenow98 morenow98 self-assigned this Sep 3, 2024
Copy link
Contributor

@InHyeok-J InHyeok-J left a comment

Choose a reason for hiding this comment

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

LGTM

Comment on lines +51 to +55
.requestMatchers(
Arrays.stream(REGEX_WHITE_LIST)
.map(RegexRequestMatcher::regexMatcher)
.toArray(RegexRequestMatcher[]::new)
).permitAll()
Copy link
Contributor

Choose a reason for hiding this comment

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

정규표현식분리한건 너무 좋음

Comment on lines +77 to +79
String errorMessage = e.getMessage() +
" " +
CommonErrorCode.INTERNAL_SERVER_ERROR.getMessage();
Copy link
Contributor

Choose a reason for hiding this comment

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

이거 저번에 말한거같은데 Builder 대신 쓰는 이유가 있는지?

Copy link
Member Author

Choose a reason for hiding this comment

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

그 떄 말한 거 때문에 좀 더 자세히 검색해보고 바꿨어. 커밋 메시지에도 써놨는데

요거 참고해도 좋을 듯

Copy link
Contributor

Choose a reason for hiding this comment

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

굳이 사용하지 않아도 된다구나 오키요

@morenow98 morenow98 merged commit d745b00 into develop Sep 3, 2024
1 check passed
@morenow98 morenow98 deleted the feature/60-find-problem-detail-elastic branch September 6, 2024 10:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

문제 상세 조회 API 구현
2 participants