opt
This commit is contained in:
parent
276773131c
commit
25f0ef9cf2
@ -15,19 +15,11 @@ import com.knowledge.base.infrastructure.north.dto.doc.OSRecordDTO;
|
||||
import com.knowledge.base.infrastructure.north.dto.user.UserDTO;
|
||||
import com.knowledge.base.infrastructure.north.dto.user.UserFileDTO;
|
||||
import com.knowledge.base.infrastructure.north.dto.user.UserTokenDTO;
|
||||
import com.knowledge.base.infrastructure.south.es.FileElasticsearchGateway;
|
||||
import com.knowledge.base.infrastructure.util.CacheUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.elasticsearch.action.search.SearchRequest;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
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.SearchHit;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -49,7 +41,7 @@ public class FileQueryController {
|
||||
|
||||
private final UserAppService userAppService;
|
||||
|
||||
private final RestHighLevelClient esClient;
|
||||
private final FileElasticsearchGateway esGateway;
|
||||
|
||||
@Autowired
|
||||
private FileCacheService fileCacheService;
|
||||
@ -64,17 +56,12 @@ public class FileQueryController {
|
||||
public Map<String, Object> search(@RequestBody SearchReq requestBody) throws IOException {
|
||||
int page = requestBody.getPage() != null && requestBody.getPage() > 0 ? requestBody.getPage() : 1;
|
||||
int size = requestBody.getSize() != null && requestBody.getSize() > 0 ? requestBody.getSize() : defaultPageSize;
|
||||
int from = (page - 1) * size;
|
||||
|
||||
SearchSourceBuilder builder = new SearchSourceBuilder()
|
||||
.query(buildSearchQuery(requestBody.getKeywordGroups()))
|
||||
.from(from)
|
||||
.size(size)
|
||||
.sort("mtime", SortOrder.DESC);
|
||||
|
||||
SearchRequest request = new SearchRequest("documents").source(builder);
|
||||
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
|
||||
|
||||
SearchResponse response = esGateway.searchFileDocuments(
|
||||
requestBody.getKeywordGroups(),
|
||||
page,
|
||||
size
|
||||
);
|
||||
return buildSearchResponse(response, requestBody.getFlatKeywords(), page, size);
|
||||
}
|
||||
|
||||
@ -171,26 +158,6 @@ public class FileQueryController {
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
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);
|
||||
// 东八区时间点
|
||||
outerQuery.filter(QueryBuilders.rangeQuery("expireTime")
|
||||
.gte(System.currentTimeMillis())
|
||||
.timeZone("+08:00"));
|
||||
return outerQuery;
|
||||
}
|
||||
|
||||
|
||||
private Map<String, Object> buildSearchResponse(SearchResponse response, List<String> keywords, int page, int size) {
|
||||
List<Map<String, Object>> results = new ArrayList<>();
|
||||
|
||||
@ -14,14 +14,11 @@ import com.knowledge.base.infrastructure.config.DynamicConfig;
|
||||
import com.knowledge.base.infrastructure.config.ObjectStorageProperties;
|
||||
import com.knowledge.base.infrastructure.north.dto.doc.OSRecordDTO;
|
||||
import com.knowledge.base.infrastructure.north.dto.user.UserDTO;
|
||||
import com.knowledge.base.infrastructure.south.es.FileElasticsearchGateway;
|
||||
import com.knowledge.base.infrastructure.south.minio.ObjectStorageGateway;
|
||||
import com.knowledge.base.infrastructure.util.DateUtil;
|
||||
import com.knowledge.base.infrastructure.util.ThreadPoolUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -43,10 +40,9 @@ import java.util.stream.Collectors;
|
||||
public class FileWriteController {
|
||||
private static final Logger logger = LoggerFactory.getLogger(FileWriteController.class);
|
||||
|
||||
private final RestHighLevelClient esClient;
|
||||
private final FileElasticsearchGateway esGateway;
|
||||
|
||||
private final FileCacheService fileCacheService;
|
||||
private static final String INDEX_NAME = "documents";
|
||||
|
||||
private final DynamicConfig dynamicConfig;
|
||||
|
||||
@ -93,11 +89,7 @@ public class FileWriteController {
|
||||
fileCacheService.clearAll();
|
||||
|
||||
// 2. 清空 ES documents 索引所有文档
|
||||
DeleteByQueryRequest deleteRequest = new DeleteByQueryRequest(INDEX_NAME);
|
||||
deleteRequest.setQuery(QueryBuilders.matchAllQuery());
|
||||
esClient.deleteByQuery(deleteRequest, RequestOptions.DEFAULT);
|
||||
|
||||
logger.warn("已清空 ES 和缓存中所有文件相关数据!");
|
||||
esGateway.clearAllFileDocuments();
|
||||
return ResponseEntity.ok(Map.of("msg", "所有文件相关数据已清空"));
|
||||
} catch (Exception e) {
|
||||
logger.error("全量清空失败", e);
|
||||
|
||||
@ -10,11 +10,17 @@ import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||
import org.elasticsearch.index.reindex.BulkByScrollResponse;
|
||||
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.action.search.SearchRequest;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -35,6 +41,55 @@ public class FileElasticsearchGateway {
|
||||
@Autowired
|
||||
private RestHighLevelClient esClient;
|
||||
|
||||
public SearchResponse searchFileDocuments(List<List<String>> keywordGroups, int page, int size) {
|
||||
try {
|
||||
int from = (page - 1) * size;
|
||||
QueryBuilder query = buildSearchQuery(keywordGroups);
|
||||
|
||||
SearchSourceBuilder builder = new SearchSourceBuilder()
|
||||
.query(query)
|
||||
.from(from)
|
||||
.size(size)
|
||||
.sort("mtime", SortOrder.DESC);
|
||||
|
||||
SearchRequest request = new SearchRequest(INDEX_NAME).source(builder);
|
||||
return esClient.search(request, RequestOptions.DEFAULT);
|
||||
} catch (Exception e) {
|
||||
log.error("searchFileDocuments 查询失败", e);
|
||||
throw new RuntimeException("文件搜索失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建支持中文分词的多字段搜索查询(filename + content)
|
||||
*/
|
||||
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.boolQuery()
|
||||
.should(QueryBuilders.matchQuery("filename", keyword).analyzer("ik_smart"))
|
||||
.should(QueryBuilders.matchQuery("content", keyword).analyzer("ik_smart"))
|
||||
);
|
||||
}
|
||||
|
||||
outerQuery.should(groupQuery);
|
||||
}
|
||||
|
||||
outerQuery.minimumShouldMatch(1);
|
||||
|
||||
// 过滤掉过期文件
|
||||
outerQuery.filter(QueryBuilders.rangeQuery("expireTime")
|
||||
.gte(System.currentTimeMillis())
|
||||
.timeZone("+08:00"));
|
||||
|
||||
return outerQuery;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据 filepath 批量删除文档
|
||||
*
|
||||
@ -130,5 +185,21 @@ public class FileElasticsearchGateway {
|
||||
log.error("ES 写入文档失败: index={}, docId={}", index, docId, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAllFileDocuments() {
|
||||
try {
|
||||
DeleteByQueryRequest deleteRequest = new DeleteByQueryRequest(INDEX_NAME);
|
||||
deleteRequest.setQuery(QueryBuilders.matchAllQuery());
|
||||
deleteRequest.setConflicts("proceed");
|
||||
deleteRequest.setRefresh(true);
|
||||
|
||||
BulkByScrollResponse response = esClient.deleteByQuery(deleteRequest, RequestOptions.DEFAULT);
|
||||
log.warn("已清空 ES 索引 [{}],共删除文档数: {}", INDEX_NAME, response.getDeleted());
|
||||
} catch (Exception e) {
|
||||
log.error("清空 ES 索引 [{}] 失败", INDEX_NAME, e);
|
||||
throw new RuntimeException("清空 ES 索引失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user