Skip to content

Commit 0c25473

Browse files
committed
🐛 修复模糊文本的聚合搜索结果为空(相似度过低被忽略)
1 parent 1a2e48a commit 0c25473

File tree

2 files changed

+44
-27
lines changed

2 files changed

+44
-27
lines changed

src/main/java/com/pcdd/sonovel/action/AggregatedSearchAction.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import lombok.SneakyThrows;
1313

1414
import java.util.ArrayList;
15+
import java.util.Collections;
1516
import java.util.List;
1617
import java.util.Scanner;
1718
import java.util.concurrent.CountDownLatch;
@@ -49,29 +50,31 @@ public void execute() {
4950

5051
@SneakyThrows
5152
public static List<SearchResult> getSearchResults(String kw) {
52-
List<List<SearchResult>> results = new ArrayList<>();
53+
List<SearchResult> results = Collections.synchronizedList(new ArrayList<>());
5354
List<Source> searchableSources = SourceUtils.getSearchableSources();
5455
ExecutorService threadPool = Executors.newFixedThreadPool(searchableSources.size());
5556
CountDownLatch latch = new CountDownLatch(searchableSources.size());
5657

5758
for (Source source : searchableSources) {
5859
threadPool.execute(() -> {
59-
List<SearchResult> res = new SearchParser(source.config).parse(kw);
60-
61-
if (CollUtil.isNotEmpty(res)) {
62-
Rule rule = source.rule;
63-
Console.log("<== 书源 {} ({})\t搜索到 {} 条记录", rule.getId(), rule.getName(), res.size());
64-
results.add(res);
60+
try {
61+
List<SearchResult> res = new SearchParser(source.config).parse(kw);
62+
if (CollUtil.isNotEmpty(res)) {
63+
Rule rule = source.rule;
64+
Console.log("<== 书源 {} ({})\t搜索到 {} 条记录", rule.getId(), rule.getName(), res.size());
65+
results.addAll(res);
66+
}
67+
} catch (Exception e) {
68+
Console.error("搜索源 {} 异常:{}", source.rule.getName(), e.getMessage());
69+
} finally {
70+
latch.countDown();
6571
}
66-
67-
latch.countDown();
6872
});
6973
}
7074

7175
latch.await();
72-
List<SearchResult> flatList = new ArrayList<>();
73-
results.forEach(flatList::addAll);
74-
return SearchResultsHandler.aggregateSort(flatList, kw);
76+
threadPool.shutdown();
77+
return SearchResultsHandler.aggregateSort(results, kw);
7578
}
7679

7780
}

src/main/java/com/pcdd/sonovel/handle/SearchResultsHandler.java

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,36 @@ public static List<SearchResult> aggregateSort(List<SearchResult> data, String k
4242
double authorScore = getSimilarity(data, kw, "author");
4343
boolean isAuthorSearch = bookNameScore < authorScore;
4444

45-
return data.stream()
46-
// 筛选相似度大于 0.3 的记录
47-
.filter(sr -> StrUtil.similar(kw, isAuthorSearch ? sr.getAuthor() : sr.getBookName()) > 0.3)
48-
.sorted((o1, o2) -> {
49-
double score1 = StrUtil.similar(kw, isAuthorSearch ? o1.getAuthor() : o1.getBookName());
50-
double score2 = StrUtil.similar(kw, isAuthorSearch ? o2.getAuthor() : o2.getBookName());
51-
52-
if (score1 != score2) {
53-
return Double.compare(score2, score1); // 按相似度降序
54-
}
55-
56-
return isAuthorSearch
57-
? o1.getBookName().compareTo(o2.getBookName()) // 按书名升序
58-
: o1.getAuthor().compareTo(o2.getAuthor()); // 按作者升序
59-
})
45+
// 缓存相似度
46+
Map<SearchResult, Double> similarityMap = new HashMap<>();
47+
for (SearchResult sr : data) {
48+
String target = isAuthorSearch ? sr.getAuthor() : sr.getBookName();
49+
double score = StrUtil.similar(kw, target);
50+
similarityMap.put(sr, score);
51+
}
52+
53+
// 排序器统一封装,复用
54+
Comparator<SearchResult> comparator = (o1, o2) -> {
55+
double score1 = similarityMap.get(o1);
56+
double score2 = similarityMap.get(o2);
57+
if (score1 != score2) {
58+
return Double.compare(score2, score1); // 按相似度降序
59+
}
60+
return isAuthorSearch
61+
? o1.getBookName().compareTo(o2.getBookName())
62+
: o1.getAuthor().compareTo(o2.getAuthor());
63+
};
64+
65+
// 筛选相似度高的
66+
List<SearchResult> filtered = data.stream()
67+
.filter(sr -> similarityMap.get(sr) > 0.3)
68+
.sorted(comparator)
6069
.toList();
70+
71+
// 如果筛选后为空,则排序原始 data 返回
72+
return filtered.isEmpty()
73+
? data.stream().filter(sr -> similarityMap.get(sr) > 0).sorted(comparator).toList()
74+
: filtered;
6175
}
6276

6377
// 计算权重,用于判断关键字是书名还是作者

0 commit comments

Comments
 (0)