Skip to content

Commit 4628fbf

Browse files
authored
Merge pull request #720 from Team-TicketMate/test
Test
2 parents b9e1332 + c8194dd commit 4628fbf

3 files changed

Lines changed: 78 additions & 86 deletions

File tree

ticketmate-ai/src/main/java/com/ticketmate/backend/ai/application/service/VertexAiEmbeddingService.java

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,13 @@ public class VertexAiEmbeddingService {
4040
* @param embeddingType CONCERT, AGENT, SEARCH
4141
*/
4242
@Transactional
43-
@Caching(
44-
cacheable = @Cacheable(
45-
value = "embeddings",
46-
key = "T(com.ticketmate.backend.common.core.util.CommonUtil)"
47-
+ ".normalizeAndRemoveSpecialCharacters(#text)"
48-
+ "+':' + #embeddingType",
49-
condition = "#targetId == null",
50-
unless = "#result == null"
51-
)
52-
)
5343
public Embedding fetchOrGenerateEmbedding(UUID targetId, String text, EmbeddingType embeddingType) {
5444
// 텍스트 정규화
5545
String normalizeText = CommonUtil.normalizeAndRemoveSpecialCharacters(text);
5646

5747
// 검색 모드: 캐시나 DB 조회 후 없으면 생성
5848
return embeddingRepository.findByTextAndEmbeddingType(normalizeText, embeddingType)
59-
.orElseGet(() -> createAndSaveEmbedding(targetId, normalizeText, embeddingType));
49+
.orElseGet(() -> createAndSaveEmbedding(targetId, normalizeText, embeddingType));
6050
}
6151

6252
/**
@@ -67,11 +57,11 @@ private Embedding createAndSaveEmbedding(UUID targetId, String normalizedText, E
6757
float[] vector = extractVector(generateEmbedding(normalizedText));
6858

6959
return embeddingRepository.save(Embedding.builder()
70-
.targetId(targetId)
71-
.text(normalizedText)
72-
.embeddingVector(vector)
73-
.embeddingType(type)
74-
.build());
60+
.targetId(targetId)
61+
.text(normalizedText)
62+
.embeddingVector(vector)
63+
.embeddingType(type)
64+
.build());
7565
}
7666

7767
/**
@@ -83,9 +73,9 @@ private Embedding createAndSaveEmbedding(UUID targetId, String normalizedText, E
8373
private EmbedContentResponse generateEmbedding(String text) {
8474
try {
8575
return genAiClient.models.embedContent(
86-
googleGenAIProperties.model(),
87-
text,
88-
EmbedContentConfig.builder().build()
76+
googleGenAIProperties.model(),
77+
text,
78+
EmbedContentConfig.builder().build()
8979
);
9080
} catch (ClientException e) {
9181
log.error("Vertex AI 임베딩 API 호출 실패: {}", e.getMessage());
@@ -101,9 +91,9 @@ private EmbedContentResponse generateEmbedding(String text) {
10191
*/
10292
private float[] extractVector(EmbedContentResponse response) {
10393
List<Float> embeddingValues = response.embeddings()
104-
.flatMap(list -> list.stream().findFirst())
105-
.flatMap(ContentEmbedding::values)
106-
.orElseThrow(() -> new CustomException(ErrorCode.EMBEDDING_DATA_NOT_FOUND));
94+
.flatMap(list -> list.stream().findFirst())
95+
.flatMap(ContentEmbedding::values)
96+
.orElseThrow(() -> new CustomException(ErrorCode.EMBEDDING_DATA_NOT_FOUND));
10797
int size = embeddingValues.size();
10898
float[] vector = new float[size];
10999
for (int i = 0; i < size; i++) {

ticketmate-ai/src/main/java/com/ticketmate/backend/ai/infrastructure/repository/EmbeddingRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public interface EmbeddingRepository extends JpaRepository<Embedding, UUID> {
2525
*/
2626
@Query(value = "SELECT target_id FROM embedding e "
2727
+ "WHERE e.embedding_type = 'CONCERT' "
28+
+ "AND (e.embedding_vector <-> CAST(:vector AS vector)) <= 0.90 "
2829
+ "AND EXISTS "
2930
+ "(SELECT 1 FROM ticket_open_date t "
3031
+ "JOIN concert c ON t.concert_concert_id = c.concert_id "
@@ -43,6 +44,7 @@ public interface EmbeddingRepository extends JpaRepository<Embedding, UUID> {
4344
*/
4445
@Query(value = "SELECT target_id FROM embedding "
4546
+ "WHERE embedding_type = 'AGENT' "
47+
+ "AND (embedding_vector <-> CAST(:vector AS vector)) <= 0.90 "
4648
+ "ORDER BY embedding_vector <-> CAST(:vector AS vector) LIMIT :limit", nativeQuery = true)
4749
List<UUID> findNearestAgentEmbeddings(@Param("vector") float[] vector, @Param("limit") int limit);
4850

ticketmate-search/src/main/java/com/ticketmate/backend/search/infrastructure/repository/SearchRepositoryImpl.java

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -50,44 +50,44 @@ public List<ConcertSearchInfo> findConcertDetailsByIds(List<UUID> concertIds) {
5050
return Collections.emptyList();
5151
}
5252
return queryFactory
53-
.select(Projections.constructor(ConcertSearchInfo.class,
54-
CONCERT.concertId,
55-
CONCERT.concertName,
56-
CONCERT_HALL.concertHallName,
57-
// 선예매 오픈일
58-
Expressions.dateTimeTemplate(
59-
Instant.class,
60-
"min({0})",
61-
new CaseBuilder()
62-
.when(TICKET_OPEN_DATE.ticketOpenType.eq(TicketOpenType.PRE_OPEN))
63-
.then(TICKET_OPEN_DATE.openDate)
64-
.otherwise((Instant) null)
65-
).as("ticketPreOpenDate"),
66-
// 일반 예매 오픈일
67-
Expressions.dateTimeTemplate(
68-
Instant.class,
69-
"min({0})",
70-
new CaseBuilder()
71-
.when(TICKET_OPEN_DATE.ticketOpenType.eq(TicketOpenType.GENERAL_OPEN))
72-
.then(TICKET_OPEN_DATE.openDate)
73-
.otherwise((Instant) null)
74-
).as("ticketGeneralOpenDate"),
75-
CONCERT_DATE.performanceDate.min().as("startDate"),
76-
CONCERT_DATE.performanceDate.max().as("endDate"),
77-
CONCERT.concertThumbnailStoredPath,
78-
Expressions.constant(0.0)
79-
))
80-
.from(CONCERT)
81-
.leftJoin(CONCERT.concertHall, CONCERT_HALL)
82-
.join(CONCERT_DATE).on(CONCERT.eq(CONCERT_DATE.concert))
83-
.join(TICKET_OPEN_DATE).on(CONCERT.eq(TICKET_OPEN_DATE.concert))
84-
.where(CONCERT.concertId.in(concertIds))
85-
.groupBy(CONCERT.concertId,
86-
CONCERT.concertName,
87-
CONCERT_HALL.concertHallName,
88-
CONCERT.concertThumbnailStoredPath
89-
)
90-
.fetch();
53+
.select(Projections.constructor(ConcertSearchInfo.class,
54+
CONCERT.concertId,
55+
CONCERT.concertName,
56+
CONCERT_HALL.concertHallName,
57+
// 선예매 오픈일
58+
Expressions.dateTimeTemplate(
59+
Instant.class,
60+
"min({0})",
61+
new CaseBuilder()
62+
.when(TICKET_OPEN_DATE.ticketOpenType.eq(TicketOpenType.PRE_OPEN))
63+
.then(TICKET_OPEN_DATE.openDate)
64+
.otherwise((Instant) null)
65+
).as("ticketPreOpenDate"),
66+
// 일반 예매 오픈일
67+
Expressions.dateTimeTemplate(
68+
Instant.class,
69+
"min({0})",
70+
new CaseBuilder()
71+
.when(TICKET_OPEN_DATE.ticketOpenType.eq(TicketOpenType.GENERAL_OPEN))
72+
.then(TICKET_OPEN_DATE.openDate)
73+
.otherwise((Instant) null)
74+
).as("ticketGeneralOpenDate"),
75+
CONCERT_DATE.performanceDate.min().as("startDate"),
76+
CONCERT_DATE.performanceDate.max().as("endDate"),
77+
CONCERT.concertThumbnailStoredPath,
78+
Expressions.constant(0.0)
79+
))
80+
.from(CONCERT)
81+
.leftJoin(CONCERT.concertHall, CONCERT_HALL)
82+
.join(CONCERT_DATE).on(CONCERT.eq(CONCERT_DATE.concert))
83+
.join(TICKET_OPEN_DATE).on(CONCERT.eq(TICKET_OPEN_DATE.concert))
84+
.where(CONCERT.concertId.in(concertIds))
85+
.groupBy(CONCERT.concertId,
86+
CONCERT.concertName,
87+
CONCERT_HALL.concertHallName,
88+
CONCERT.concertThumbnailStoredPath
89+
)
90+
.fetch();
9191
}
9292

9393
/**
@@ -102,20 +102,20 @@ public List<AgentSearchInfo> findAgentDetailsByIds(List<UUID> agentIds) {
102102
return Collections.emptyList();
103103
}
104104
return queryFactory
105-
.select(Projections.constructor(AgentSearchInfo.class,
106-
MEMBER.memberId,
107-
MEMBER.nickname,
108-
MEMBER.profileImgStoredPath,
109-
PORTFOLIO.portfolioDescription,
110-
AGENT_PERFORMANCE_SUMMARY.averageRating,
111-
AGENT_PERFORMANCE_SUMMARY.reviewCount,
112-
Expressions.constant(0.0)
113-
))
114-
.from(MEMBER)
115-
.leftJoin(PORTFOLIO).on(PORTFOLIO.member.eq(MEMBER))
116-
.innerJoin(AGENT_PERFORMANCE_SUMMARY).on(MEMBER.eq(AGENT_PERFORMANCE_SUMMARY.agent))
117-
.where(MEMBER.memberId.in(agentIds))
118-
.fetch();
105+
.select(Projections.constructor(AgentSearchInfo.class,
106+
MEMBER.memberId,
107+
MEMBER.nickname,
108+
MEMBER.profileImgStoredPath,
109+
PORTFOLIO.portfolioDescription,
110+
AGENT_PERFORMANCE_SUMMARY.averageRating,
111+
AGENT_PERFORMANCE_SUMMARY.reviewCount,
112+
Expressions.constant(0.0)
113+
))
114+
.from(MEMBER)
115+
.leftJoin(PORTFOLIO).on(PORTFOLIO.member.eq(MEMBER))
116+
.innerJoin(AGENT_PERFORMANCE_SUMMARY).on(MEMBER.eq(AGENT_PERFORMANCE_SUMMARY.agent))
117+
.where(MEMBER.memberId.in(agentIds))
118+
.fetch();
119119
}
120120

121121
/**
@@ -129,21 +129,21 @@ public List<AgentSearchInfo> findAgentDetailsByIds(List<UUID> agentIds) {
129129
public List<UUID> findAgentIdsByKeyword(String keyword, int limit) {
130130
// 동적 WHERE 절 조합
131131
BooleanExpression whereClause = QueryDslUtil.allOf(
132-
MEMBER.memberType.eq(MemberType.AGENT),
133-
QueryDslUtil.anyOf(
134-
QueryDslUtil.likeIgnoreCase(MEMBER.nickname, keyword),
135-
QueryDslUtil.likeIgnoreCase(PORTFOLIO.portfolioDescription, keyword)
136-
)
132+
MEMBER.memberType.eq(MemberType.AGENT),
133+
QueryDslUtil.anyOf(
134+
QueryDslUtil.likeIgnoreCase(MEMBER.nickname, keyword),
135+
QueryDslUtil.likeIgnoreCase(PORTFOLIO.portfolioDescription, keyword)
136+
)
137137
);
138138

139139
return queryFactory
140-
.select(MEMBER.memberId)
141-
.from(MEMBER)
142-
.innerJoin(PORTFOLIO)
143-
.on((PORTFOLIO.member).eq(MEMBER))
144-
.where(whereClause)
145-
.limit(limit)
146-
.fetch();
140+
.select(MEMBER.memberId)
141+
.from(MEMBER)
142+
.innerJoin(PORTFOLIO)
143+
.on((PORTFOLIO.member).eq(MEMBER))
144+
.where(whereClause)
145+
.limit(limit)
146+
.fetch();
147147
}
148148

149149
/**

0 commit comments

Comments
 (0)