fix: 第17轮搜索审计修复 — 缓存键中毒/_pubmed_conditions异常保护/引号短语exact强制
CI / backend (push) Canceled after 0s
CI / frontend (push) Canceled after 0s

- P0-1 (HIGH): sub-path A query原地修改后缓存键未更新 → 重新计算
- P0-2 (MEDIUM): _pubmed_conditions无异常保护 → try/except降级flat text
- P0-3 (MEDIUM): 引号短语不强制exact_phrase → _phrase_terms_set跟踪
This commit is contained in:
34047007@qq.com
2026-07-28 15:12:13 +08:00
parent de1f4a4bb8
commit 5fa2fbec7b
2 changed files with 87 additions and 6 deletions
+41 -1
View File
@@ -1210,7 +1210,7 @@
## 第十六轮:第 16 轮审计修复(4 项修复 + 3 项记录)
**日期**2026-07-29
**提交**`(待推送)`
**提交**`de1f4a4`
**数量**:4 项修复 + 3 项记录
**触发**:用户第 11 次要求全面检查(Round 163 并行 agentNormal 搜索边缘、前端参数、NOT 检测)
**测试**1007 全部通过 + 前端 build 通过
@@ -1253,6 +1253,46 @@
---
## 第十七轮:第 17 轮审计修复(3 项)
**日期**2026-07-29
**提交**`(待推送)`
**数量**3 项(1 HIGH + 2 MEDIUM
**触发**:用户第 12 次要求全面检查(Round 173 并行 agent`_is_flat_text` 降级路径、facet 一致性、前端参数映射)
**审计**:facet 一致性和缓存键验证通过,未发现问题
**测试**1007 全部通过 + 前端 build 通过
### P0-1 (HIGH): `_search_cache_key` 在 sub-path A 中被污染
- **文件**`search_engine.py:314-318`
- **根因**`_search_cache_key` 在第 186 行用原始 `query` 预计算。第 314-318 行在 sub-path A 中对 `query` 原地修改(剥离 field tags/布尔符/引号/括号),但缓存键未更新。后续请求命中此缓存时,返回的是剥离后的空查询结果。
- **触发条件**:仅当 `is_pubmed_syntax(query)=True` 但 `parse_pubmed_query(query)` 返回空有效字段时(如 `"NOT"`、`"AND OR"` 等无意义查询)。实际影响极小,但属于正确性 bug。
- **修复**:在 `query` 原地修改后重新调用 `_search_cache_key()` 和 `_facet_cache_key()`,确保缓存键反映剥离后的查询内容。
### P0-2 (MEDIUM): `_pubmed_conditions` 无异常保护
- **文件**`search_engine.py:282-284`
- **根因**`_pubmed_conditions()` 调用无 try/except。内部虽有零散异常处理,但 `AttributeError`/`TypeError` 等会传播到 `search()` 外 → 500 错误(`literature.py:330` 已有全局保护,但高级搜索引擎没有)。
- **修复**:包裹 try/except Exception,异常时 `logger.exception()` 并降级到 flat text 路径:`_is_flat_text = True; conditions = []`
### P0-3 (MEDIUM): 引号短语不强制 exact_phrase
- **文件**`search_engine.py:334-393`
- **根因**flat text 路径从查询中提取引号短语 `"lung cancer"` 作为独立词,但传入 `_field_condition(term, exact_phrase)` 时使用全局 `exact_phrase` 参数。`exact_phrase=False` 时,引号短语被拆散为 `lung AND cancer` 而非保持 `<->` 短语搜索。
- **修复**:记录引号短语集 `_phrase_terms_set`,传入 `_field_condition` 时:引号短语始终 `exact=True`,其他词使用全局 `exact_phrase`。
### 审计结果汇总
| 审计维度 | 结果 |
|---------|------|
| `_is_flat_text` 降级路径 | ✅ 缓存键中毒(P0-1)已修复、异常保护(P0-2)已添加、引号短语(P0-3)已修复 |
| Fragment/缓存完整性 | ✅ `parse_pubmed_query` 异常降级 clean、回退路径比普通搜索更全面 |
| `year_counts` facet 一致性 | ✅ 筛选条件与主查询完全一致、缓存键差异仅限于分页参数(设计意图)、无问题 |
| Facet 缓存键完备性 | ✅ `_facet_cache_key` 包含全部 26 个筛选参数,无缺失 |
| 前端参数映射 | ✅ SearchView.vue 发送全部 28 个参数、HomeView 参数子集缩小属设计意图、`is_oa` 后端功能被 `is_free_full_text` 覆盖、无实际 gap |
---
截至 2026-07-29,剩余 7 项已知限制:
| ID | 问题 | 原因 | 影响 |