From 62791e5553813a8e7a3be2b1c8788060c0f00f67 Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 21 May 2025 22:54:40 +0800 Subject: [PATCH] add single query method --- .../north/controller/SearchController.java | 63 ++++++++++++++----- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/doc/parser/infrastructure/north/controller/SearchController.java b/src/main/java/com/doc/parser/infrastructure/north/controller/SearchController.java index 58e07cb..28be3fa 100644 --- a/src/main/java/com/doc/parser/infrastructure/north/controller/SearchController.java +++ b/src/main/java/com/doc/parser/infrastructure/north/controller/SearchController.java @@ -6,9 +6,11 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.*; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.MultiMatchQueryBuilder; +import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.SortOrder; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; @@ -40,21 +42,8 @@ public class SearchController { int size = requestBody.getSize() != null && requestBody.getSize() > 0 ? requestBody.getSize() : defaultPageSize; int from = (page - 1) * size; - // 构建外层 OR 查询 - BoolQueryBuilder outerQuery = QueryBuilders.boolQuery(); - for (List group : requestBody.getKeywordGroups()) { - BoolQueryBuilder groupQuery = QueryBuilders.boolQuery(); - for (String keyword : group) { - // 使用 match_phrase 精确匹配短语 - groupQuery.must(QueryBuilders.multiMatchQuery(keyword, "filename", "content") - .type(MultiMatchQueryBuilder.Type.PHRASE)); - } - outerQuery.should(groupQuery); - } - outerQuery.minimumShouldMatch(1); // 至少匹配一组 - SearchSourceBuilder builder = new SearchSourceBuilder() - .query(outerQuery) + .query(buildSearchQuery(requestBody.getKeywordGroups())) .from(from) .size(size) .sort("mtime", SortOrder.DESC); @@ -62,7 +51,50 @@ public class SearchController { SearchRequest request = new SearchRequest("documents").source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); + return buildSearchResponse(response, requestBody.getFlatKeywords(), page, size); + } + + @GetMapping + public Map search(@RequestParam String q) throws IOException { + int page = 1; + int size = defaultPageSize; + int from = 0; + + // 单关键词转换成一组组结构 + List> keywordGroups = Collections.singletonList(Collections.singletonList(q)); + List flatKeywords = Collections.singletonList(q); + + SearchSourceBuilder builder = new SearchSourceBuilder() + .query(buildSearchQuery(keywordGroups)) + .from(from) + .size(size) + .sort("mtime", SortOrder.DESC); + + SearchRequest request = new SearchRequest("documents").source(builder); + SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); + + return buildSearchResponse(response, flatKeywords, page, size); + } + + private QueryBuilder buildSearchQuery(List> keywordGroups) { + BoolQueryBuilder outerQuery = QueryBuilders.boolQuery(); + + for (List group : keywordGroups) { + BoolQueryBuilder groupQuery = QueryBuilders.boolQuery(); + for (String keyword : group) { + groupQuery.must(QueryBuilders.multiMatchQuery(keyword, "filename", "content") + .type(MultiMatchQueryBuilder.Type.PHRASE)); + } + outerQuery.should(groupQuery); + } + + outerQuery.minimumShouldMatch(1); + return outerQuery; + } + + private Map buildSearchResponse(SearchResponse response, List keywords, int page, int size) { List> results = new ArrayList<>(); + for (SearchHit hit : response.getHits()) { Map source = hit.getSourceAsMap(); Map result = new LinkedHashMap<>(); @@ -71,7 +103,7 @@ public class SearchController { result.put("mtime", source.get("mtime")); String content = (String) source.get("content"); - String summary = extractMultiSnippet(content, requestBody.getFlatKeywords(), 50); + String summary = extractMultiSnippet(content, keywords, 50); result.put("summary", summary); results.add(result); @@ -85,6 +117,7 @@ public class SearchController { return responseBody; } + private String extractMultiSnippet(String content, List keywords, int contextLength) { if (content == null || keywords == null || keywords.isEmpty()) return "";