docs: 新增第10轮搜索审计修复记录(缓存键碰撞/OR语义/affiliation/前端OR和精确短语)
This commit is contained in:
+58
-3
@@ -2,9 +2,9 @@
|
||||
|
||||
> 本文档按修复轮次详细记录所有搜索功能合规性修复的背景、根因分析和修改内容。
|
||||
>
|
||||
> **累计**:9 轮,115 项修复,50+ 字段标签注册,1007 项测试覆盖,7 项已知限制
|
||||
> **累计**:10 轮,121 项修复,50+ 字段标签注册,1007 项测试覆盖,7 项已知限制
|
||||
> **时间跨度**:2026-07-24 ~ 2026-07-28
|
||||
> **核心文件**:`pubmed_query_parser.py`(~730 行)→ `search_engine.py`(~1320 行)
|
||||
> **核心文件**:`pubmed_query_parser.py`(~730 行)→ `search_engine.py`(~1350 行)
|
||||
|
||||
---
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
7. [第七轮:第 7 轮深度审计修复(20 项)](#第七轮第-7-轮深度审计修复)
|
||||
8. [第八轮:第 8 轮深度审计修复(12 项)](#第八轮第-8-轮深度审计修复)
|
||||
9. [第九轮:第 9 轮深度审计修复(5 项)](#第九轮第-9-轮深度审计修复)
|
||||
10. [遗留限制](#遗留限制)
|
||||
10. [第十轮:第 10 轮深度审计修复(6 项)](#第十轮第-10-轮深度审计修复)
|
||||
11. [遗留限制](#遗留限制)
|
||||
|
||||
---
|
||||
|
||||
@@ -773,6 +774,60 @@
|
||||
|
||||
---
|
||||
|
||||
## 第十轮:第 10 轮深度审计修复(6 项)
|
||||
|
||||
**日期**:2026-07-28
|
||||
**提交**:`a985d07`
|
||||
**数量**:6 项
|
||||
**测试**:1007 全部通过 + 前端 build 通过
|
||||
|
||||
### P10-1: 缓存键 PubMed/纯文本路径碰撞(MEDIUM)
|
||||
|
||||
- **文件**:`search_engine.py:33-86,88-144`
|
||||
- **根因**:`_search_cache_key` 和 `_facet_cache_key` 只对 query 做 `strip().lower()` 归一化,不区分 PubMed 路径和纯文本路径。相同文本先走 PubMed 路径被缓存,后续纯文本路径命中同样的 key 返回不匹配的结果
|
||||
- **修复**:在 norm dict 中加入 `"pm": _is_pm(query)` 标志,两路径缓存键自动分离
|
||||
|
||||
### P10-2: OR 模式 NOT 语义错误(HIGH)
|
||||
|
||||
- **文件**:`search_engine.py:1151-1153`
|
||||
- **根因**:`boolean_operator == "or"` 路径中,代码提取 `neg_conds` 然后 `and_(pos_conds + neg_conds)`。正确语义应为 `A OR NOT B` 等价于 `A OR (NOT B)`,而非 `(A) AND (NOT B)`
|
||||
- **修复**:OR 模式直接 `or_(*term_conditions)`,不做 NOT 分离
|
||||
- **验证**:原有 `test_or_mode_mixed_not` 等测试正确通过
|
||||
|
||||
### P10-3: Affiliation 始终不在全字段搜索中(MEDIUM)
|
||||
|
||||
- **文件**:`search_engine.py:1388-1433`
|
||||
- **根因**:`_field_condition("all")` 的 5 条分支(exact/phraseto_tsquery、wildcard ILIKE、"/" 路径、中文路径、tsvector 默认)均未包含 affiliation ILIKE 兜底。虽然 tsvector 默认路径注释写"affiliation 不在 tsvector 中,以 ILIKE 兜底",但代码中并未实现
|
||||
- **修复**:所有 5 条分支均添加 `jsonb_array_elements(authors)` 的 `->>'affiliation' ILIKE` 子查询
|
||||
- **影响**:搜索"mayo clinic"或"MD Anderson"等机构名在全字段搜索中生效
|
||||
|
||||
### P10-4: 高级搜索无 query max_length(LOW)
|
||||
|
||||
- **文件**:`features.py:52`
|
||||
- **修复**:`query: str = Field("", max_length=2000)`
|
||||
- **注意**:延续 P9-5 的修复,Pydantic 层面增加长度限制
|
||||
|
||||
### P10-5: 前端缺少 OR 模式切换(MEDIUM)
|
||||
|
||||
- **文件**:`SearchView.vue:45-46,278-284,547-550`
|
||||
- **根因**:`boolean: 'and'` 硬编码,前端无法发起 OR 搜索
|
||||
- **修复**:
|
||||
- 搜索栏添加 AND/OR 选择器(NSelect)
|
||||
- `booleanOp` ref 驱动 `body.boolean`
|
||||
- URL 同步:`route.query.boolean === 'or'` 恢复
|
||||
- `resetAllFilters` 重置
|
||||
|
||||
### P10-6: 前端缺少精确短语模式(LOW)
|
||||
|
||||
- **文件**:`SearchView.vue:45-46,284,548-550`
|
||||
- **根因**:`exact_phrase` 在 TypeScript 接口中存在但从未从前端发送
|
||||
- **修复**:
|
||||
- 搜索栏添加"精确短语"复选框
|
||||
- `body.exact_phrase` 条件发送
|
||||
- URL 同步/恢复
|
||||
|
||||
---
|
||||
|
||||
## 遗留限制
|
||||
|
||||
截至 2026-07-28,剩余 7 项已知限制:
|
||||
|
||||
Reference in New Issue
Block a user