Skip to content

Commit 68e54d4

Browse files
author
marshmallowing
committed
fix: 대체검색어 로직 수정
1 parent a8af61c commit 68e54d4

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

src/main/java/com/ongil/backend/domain/search/service/SearchService.java

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -70,36 +70,46 @@ public SearchResDto search(String query, Long userId) {
7070
}
7171

7272
public List<String> recommendAlternatives(String keyword, int size) {
73-
NativeQuery nativeQuery = NativeQuery.builder()
74-
.withQuery(q -> q.bool(b -> b
75-
.should(s -> s.match(m -> m.field("brandName.autocomplete").query(keyword)))
76-
.should(s -> s.match(m -> m.field("categoryName.autocomplete").query(keyword)))
77-
.should(s -> s.match(m -> m.field("name.autocomplete").query(keyword)))
73+
NativeQuery logQuery = NativeQuery.builder()
74+
.withMaxResults(0)
75+
.withAggregation("frequent_keywords", Aggregation.of(a -> a
76+
.terms(t -> t
77+
.field("keyword")
78+
.size(200)
79+
)
7880
))
79-
.withMaxResults(50)
8081
.build();
8182

82-
SearchHits<ProductDocument> hits =
83-
elasticsearchOperations.search(nativeQuery, ProductDocument.class);
83+
SearchHits<SearchLogDocument> logHits =
84+
elasticsearchOperations.search(logQuery, SearchLogDocument.class);
85+
86+
List<String> logKeywords = new ArrayList<>();
87+
if (logHits.getAggregations() != null) {
88+
ElasticsearchAggregations aggregations = (ElasticsearchAggregations) logHits.getAggregations();
89+
ElasticsearchAggregation aggregation = aggregations.get("frequent_keywords");
90+
if (aggregation != null) {
91+
var aggregate = aggregation.aggregation().getAggregate();
92+
if (aggregate != null && aggregate.isSterms()) {
93+
logKeywords = aggregate.sterms().buckets().array().stream()
94+
.map(bucket -> bucket.key().stringValue())
95+
.toList();
96+
}
97+
}
98+
}
99+
100+
if (logKeywords.isEmpty()) {
101+
return List.of();
102+
}
84103

85104
LevenshteinDistance levenshtein = new LevenshteinDistance();
86105
String lowerKeyword = keyword.toLowerCase();
106+
int maxDistance = Math.max(2, lowerKeyword.length() / 2);
87107

88-
return hits.getSearchHits().stream()
89-
.map(hit -> {
90-
ProductDocument doc = hit.getContent();
91-
List<String> candidates = new ArrayList<>();
92-
if (doc.getBrandName() != null) candidates.add(doc.getBrandName());
93-
if (doc.getCategoryName() != null) candidates.add(doc.getCategoryName());
94-
if (doc.getName() != null) candidates.add(doc.getName());
95-
return candidates;
96-
})
97-
.flatMap(List::stream)
98-
.distinct()
99-
.sorted(Comparator.comparingInt(val ->
100-
levenshtein.apply(lowerKeyword, val.toLowerCase())
101-
))
102-
.filter(val -> !val.equalsIgnoreCase(keyword))
108+
return logKeywords.stream()
109+
.filter(k -> !k.equalsIgnoreCase(keyword))
110+
.filter(k -> k.length() >= 2)
111+
.filter(k -> levenshtein.apply(lowerKeyword, k.toLowerCase()) <= maxDistance)
112+
.sorted(Comparator.comparingInt(k -> levenshtein.apply(lowerKeyword, k.toLowerCase())))
103113
.limit(size)
104114
.toList();
105115
}

0 commit comments

Comments
 (0)