This commit is contained in:
luke 2025-06-21 08:11:03 +08:00
parent 9360afa83b
commit 9ec83eec49

View File

@ -66,7 +66,9 @@ public class FileElasticsearchGateway {
} }
/** /**
* 构建支持中文分词的多字段搜索查询filename + content * 构建支持中文和英文关键词的多字段搜索查询filename + content
* - 中文使用 match_phrase避免单字拆分
* - 英文附加 wildcard fallback提升精度
*/ */
private QueryBuilder buildSearchQuery(List<List<String>> keywordGroups) { private QueryBuilder buildSearchQuery(List<List<String>> keywordGroups) {
BoolQueryBuilder outerQuery = QueryBuilders.boolQuery(); BoolQueryBuilder outerQuery = QueryBuilders.boolQuery();
@ -75,18 +77,28 @@ public class FileElasticsearchGateway {
BoolQueryBuilder groupQuery = QueryBuilders.boolQuery(); BoolQueryBuilder groupQuery = QueryBuilders.boolQuery();
for (String keyword : group) { for (String keyword : group) {
groupQuery.must(QueryBuilders.boolQuery() BoolQueryBuilder fieldQuery = QueryBuilders.boolQuery();
.should(QueryBuilders.matchQuery(FileEsField.FILENAME, keyword).analyzer("ik_smart"))
.should(QueryBuilders.matchQuery(FileEsField.CONTENT, keyword).analyzer("ik_smart")) // 中文或长词使用 match_phrase
); fieldQuery.should(QueryBuilders.matchPhraseQuery(FileEsField.FILENAME, keyword));
fieldQuery.should(QueryBuilders.matchPhraseQuery(FileEsField.CONTENT, keyword));
// 英文或短词添加 keyword fallback ESBAPI
if (isEnglishLike(keyword)) {
fieldQuery.should(QueryBuilders.wildcardQuery("filename.keyword", "*" + keyword + "*"));
}
// 每个关键词都要求命中must
groupQuery.must(fieldQuery);
} }
// 不同关键词组之间是 or 关系should
outerQuery.should(groupQuery); outerQuery.should(groupQuery);
} }
outerQuery.minimumShouldMatch(1); outerQuery.minimumShouldMatch(1);
// 过滤掉过期文件 // 过滤过期文档
outerQuery.filter(QueryBuilders.rangeQuery(FileEsField.EXPIRE_TIME) outerQuery.filter(QueryBuilders.rangeQuery(FileEsField.EXPIRE_TIME)
.gte(System.currentTimeMillis()) .gte(System.currentTimeMillis())
.timeZone("+08:00")); .timeZone("+08:00"));
@ -94,6 +106,14 @@ public class FileElasticsearchGateway {
return outerQuery; return outerQuery;
} }
/**
* 判断关键词是否为英文或混合英文字符用于决定是否加 fallback 查询
*/
private boolean isEnglishLike(String keyword) {
if (keyword == null) return false;
return keyword.length() <= 20 && keyword.matches(".*[A-Za-z0-9]+.*");
}
/** /**
* 根据 filepath 批量删除文档 * 根据 filepath 批量删除文档