From 2c4f3a0589a93617911cf362444feb171c969117 Mon Sep 17 00:00:00 2001 From: passionryu Date: Fri, 25 Jul 2025 01:27:52 +0900 Subject: [PATCH] =?UTF-8?q?=20=F0=9F=9A=91=EF=B8=8F=20[=EB=B0=B0=ED=8F=AC?= =?UTF-8?q?=20=ED=9B=84=20=EA=B8=B4=EA=B8=89=20=EC=88=98=EC=A0=95]=20:=20?= =?UTF-8?q?=EC=A0=9C=EC=99=B8=20=ED=82=A4=EC=9B=8C=EB=93=9C=20=EC=97=86?= =?UTF-8?q?=EC=9D=84=20=EC=8B=9C=20=EB=89=B4=EC=8A=A4=20=EA=B2=80=EC=83=89?= =?UTF-8?q?=EC=9D=B4=20=EC=95=88=EB=90=98=EB=8A=94=20=EA=B2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Kakao/service/KakaoNewsService.java | 170 ++++++++++++++---- 1 file changed, 136 insertions(+), 34 deletions(-) diff --git a/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoNewsService.java b/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoNewsService.java index 2b63a54..bdbd96f 100644 --- a/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoNewsService.java +++ b/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoNewsService.java @@ -26,18 +26,17 @@ public class KakaoNewsService { private final ElasticsearchClient client; /** - * 사용자의 키워드를 리스트로 묶어 뉴스 검색 메서드에 전달합니다. + * Hot Fixed + * + * * @param includeKeywords 포함 키워드 * @param blockKeywords 제외 키워드 - * @return + * @return 뉴스 리스트 */ public List searchNews(List includeKeywords, List blockKeywords) { try { - - //전날 기준으로 시간을 측정 LocalDate yesterday = LocalDate.now().minusDays(1); - // 포함 키워드 쿼리 Query includeKeywordQuery = Query.of(q -> q .bool(b -> b .should(includeKeywords.stream() @@ -54,23 +53,6 @@ public List searchNews(List includeKeywords, List q - .bool(b -> b - .should(blockKeywords.stream() - .map(kw -> Query.of(q2 -> q2 - .multiMatch(m -> m - .query(kw) - .fields("title", "summary", "content_url", "publisher") - .type(TextQueryType.BoolPrefix) - ) - )) - .collect(Collectors.toList()) - ) - ) - ); - - // 날짜 필터 쿼리 Query dateFilter = Query.of(q -> q .range(r -> r .field("published_at") @@ -80,16 +62,43 @@ public List searchNews(List includeKeywords, List q - .bool(b -> b - .must(includeKeywordQuery) - .must(dateFilter) - .mustNot(excludeKeywordQuery) - ) - ); + // 쿼리 리스트 조합 + List mustQueries = new ArrayList<>(); + mustQueries.add(includeKeywordQuery); + mustQueries.add(dateFilter); + + // 제외 키워드가 있는 경우에만 must_not 추가 + Query finalQuery; + if (blockKeywords != null && !blockKeywords.isEmpty()) { + Query excludeKeywordQuery = Query.of(q -> q + .bool(b -> b + .should(blockKeywords.stream() + .map(kw -> Query.of(q2 -> q2 + .multiMatch(m -> m + .query(kw) + .fields("title", "summary", "content_url", "publisher") + .type(TextQueryType.BoolPrefix) + ) + )) + .collect(Collectors.toList()) + ) + ) + ); + + finalQuery = Query.of(q -> q + .bool(b -> b + .must(mustQueries) + .mustNot(excludeKeywordQuery) + ) + ); + } else { + finalQuery = Query.of(q -> q + .bool(b -> b + .must(mustQueries) + ) + ); + } - // 검색 요청 SearchRequest request = SearchRequest.of(s -> s .index("news-index-nori") .query(finalQuery) @@ -99,15 +108,12 @@ public List searchNews(List includeKeywords, List response = client.search(request, NewsEsDocument.class); - // 로그: 스코어 확인 response.hits().hits().forEach(hit -> log.info("{} | score: {}", hit.source().getTitle(), hit.score()) ); - // 결과 반환 return response.hits().hits().stream() .map(hit -> hit.source()) .collect(Collectors.toList()); @@ -117,4 +123,100 @@ public List searchNews(List includeKeywords, List searchNews(List includeKeywords, List blockKeywords) { +// try { +// +// /* 전날 기준으로 시간을 측정 */ +// LocalDate yesterday = LocalDate.now().minusDays(1); +// +// /* 포함 키워드 쿼리 */ +// Query includeKeywordQuery = Query.of(q -> q +// .bool(b -> b +// .should(includeKeywords.stream() +// .map(kw -> Query.of(q2 -> q2 +// .multiMatch(m -> m +// .query(kw) +// .fields("title", "summary", "content_url", "publisher") +// .type(TextQueryType.BoolPrefix) +// ) +// )) +// .collect(Collectors.toList()) +// ) +// .minimumShouldMatch("1") +// ) +// ); +// +// /* 제외 키워드 쿼리 */ +// Query excludeKeywordQuery = Query.of(q -> q +// .bool(b -> b +// .should(blockKeywords.stream() +// .map(kw -> Query.of(q2 -> q2 +// .multiMatch(m -> m +// .query(kw) +// .fields("title", "summary", "content_url", "publisher") +// .type(TextQueryType.BoolPrefix) +// ) +// )) +// .collect(Collectors.toList()) +// ) +// ) +// ); +// +// /* 날짜 필터 쿼리 */ +// Query dateFilter = Query.of(q -> q +// .range(r -> r +// .field("published_at") +// .gte(JsonData.of(yesterday.toString())) +// .lte(JsonData.of(yesterday.toString())) +// .format("yyyy-MM-dd") +// ) +// ); +// +// /* 전체 쿼리 조합 */ +// Query finalQuery = Query.of(q -> q +// .bool(b -> b +// .must(includeKeywordQuery) +// .must(dateFilter) +// .mustNot(excludeKeywordQuery) +// ) +// ); +// +// /* 검색 요청 */ +// SearchRequest request = SearchRequest.of(s -> s +// .index("news-index-nori") +// .query(finalQuery) +// .size(5) +// .sort(sort -> sort +// .score(sc -> sc.order(co.elastic.clients.elasticsearch._types.SortOrder.Desc)) +// ) +// ); +// +// /* 검색 수행 */ +// SearchResponse response = client.search(request, NewsEsDocument.class); +// +// /* 로그: 스코어 확인 */ +// response.hits().hits().forEach(hit -> +// log.info("{} | score: {}", hit.source().getTitle(), hit.score()) +// ); +// +// /* 결과 반환 */ +// return response.hits().hits().stream() +// .map(hit -> hit.source()) +// .collect(Collectors.toList()); +// +// } catch (IOException e) { +// log.error("키워드 기반 뉴스 검색 실패: {}", e.getMessage(), e); +// return List.of(); +// } +// } } \ No newline at end of file