add single query method
This commit is contained in:
parent
21a1179765
commit
62791e5553
@ -6,9 +6,11 @@ import org.elasticsearch.action.search.SearchResponse;
|
|||||||
import org.elasticsearch.client.*;
|
import org.elasticsearch.client.*;
|
||||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||||
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
|
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
|
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.SortOrder;
|
import org.elasticsearch.search.sort.SortOrder;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.web.bind.annotation.*;
|
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 size = requestBody.getSize() != null && requestBody.getSize() > 0 ? requestBody.getSize() : defaultPageSize;
|
||||||
int from = (page - 1) * size;
|
int from = (page - 1) * size;
|
||||||
|
|
||||||
// 构建外层 OR 查询
|
|
||||||
BoolQueryBuilder outerQuery = QueryBuilders.boolQuery();
|
|
||||||
for (List<String> 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()
|
SearchSourceBuilder builder = new SearchSourceBuilder()
|
||||||
.query(outerQuery)
|
.query(buildSearchQuery(requestBody.getKeywordGroups()))
|
||||||
.from(from)
|
.from(from)
|
||||||
.size(size)
|
.size(size)
|
||||||
.sort("mtime", SortOrder.DESC);
|
.sort("mtime", SortOrder.DESC);
|
||||||
@ -62,7 +51,50 @@ public class SearchController {
|
|||||||
SearchRequest request = new SearchRequest("documents").source(builder);
|
SearchRequest request = new SearchRequest("documents").source(builder);
|
||||||
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
|
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
|
||||||
|
|
||||||
|
return buildSearchResponse(response, requestBody.getFlatKeywords(), page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public Map<String, Object> search(@RequestParam String q) throws IOException {
|
||||||
|
int page = 1;
|
||||||
|
int size = defaultPageSize;
|
||||||
|
int from = 0;
|
||||||
|
|
||||||
|
// 单关键词转换成一组组结构
|
||||||
|
List<List<String>> keywordGroups = Collections.singletonList(Collections.singletonList(q));
|
||||||
|
List<String> 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<List<String>> keywordGroups) {
|
||||||
|
BoolQueryBuilder outerQuery = QueryBuilders.boolQuery();
|
||||||
|
|
||||||
|
for (List<String> 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<String, Object> buildSearchResponse(SearchResponse response, List<String> keywords, int page, int size) {
|
||||||
List<Map<String, Object>> results = new ArrayList<>();
|
List<Map<String, Object>> results = new ArrayList<>();
|
||||||
|
|
||||||
for (SearchHit hit : response.getHits()) {
|
for (SearchHit hit : response.getHits()) {
|
||||||
Map<String, Object> source = hit.getSourceAsMap();
|
Map<String, Object> source = hit.getSourceAsMap();
|
||||||
Map<String, Object> result = new LinkedHashMap<>();
|
Map<String, Object> result = new LinkedHashMap<>();
|
||||||
@ -71,7 +103,7 @@ public class SearchController {
|
|||||||
result.put("mtime", source.get("mtime"));
|
result.put("mtime", source.get("mtime"));
|
||||||
|
|
||||||
String content = (String) source.get("content");
|
String content = (String) source.get("content");
|
||||||
String summary = extractMultiSnippet(content, requestBody.getFlatKeywords(), 50);
|
String summary = extractMultiSnippet(content, keywords, 50);
|
||||||
result.put("summary", summary);
|
result.put("summary", summary);
|
||||||
|
|
||||||
results.add(result);
|
results.add(result);
|
||||||
@ -85,6 +117,7 @@ public class SearchController {
|
|||||||
return responseBody;
|
return responseBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String extractMultiSnippet(String content, List<String> keywords, int contextLength) {
|
private String extractMultiSnippet(String content, List<String> keywords, int contextLength) {
|
||||||
if (content == null || keywords == null || keywords.isEmpty()) return "";
|
if (content == null || keywords == null || keywords.isEmpty()) return "";
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user