# 期刊名称规范化方案

> 已基本完成，见 `scripts/dedup_global_journals.py` + 管道集成

## 问题

`global_literature.journal` 是自由文本，来自 PubMed XML 的 NLM 缩写。全库产生大量同一期刊的拼写变体：

| 类型 | 举例 |
|---|---|
| 末尾句点差异 | "Oncotarget" vs "Oncotarget." |
| 空格差异 | "Sci Rep" vs "Scientific reports" |
| 大小写差异 | "PLoS One" vs "PloS one" vs "PLOS ONE" |
| 附属信息 | "Clinical cancer research : an official journal of..." vs "Clin Cancer Res" |
| 双语 | "Biomedicine & pharmacotherapy = Biomedecine & pharmacotherapie" |

## 当前状态

### ✅ 已完成

| 项目 | 文件 | 说明 |
|------|------|------|
| 模型加 `journal_iso` | `app/models/literature.py` | GlobalLiterature 新增 NLM ISO 缩写字段 |
| 管道提取 ISOAbbreviation | `pubmed_api.py`, `pubmed_baseline.py`, `pubmed_pipeline.py` | 三处解析器均已同步 |
| 管道自动入 journal 表 | `pubmed_api.py:_ensure_journal()` | 每篇入库后自动确保期刊存在，ON CONFLICT DO NOTHING |
| 期刊去重脚本 | `scripts/dedup_global_journals.py` | ISSN 合并 + 无 ISSN 模糊合并 + 跨 ISSN 合并 + 零清理 |
| 唯一约束 | Alembic 迁移 `5bb112b00290` | `global_journals.issn` + `name` UNIQUE（去重后启用） |
| seed 跨 ISSN 合并 | `scripts/seed_global_journals.py` | 新增 pg_trgm 相似度跨 ISSN 去重 |

### 📋 数据流

```
PubMed XML → journal_iso 提取 → global_literature.journal_iso 写入
                                 → _ensure_journal()
                                     → 按 issn 匹配 GlobalJournal
                                     → 无 issn → name 精确匹配
                                     → pg_trgm 模糊兜底
                                     → 全不命中 → INSERT + ON CONFLICT DO NOTHING
```

### 🔄 未来可做

- `global_literature.journal/journal_issn` 改为 FK → `global_journals`（当前不强制，避免 ETL 复杂度）
- 定期重新跑 `seed_global_journals.py` 同步新出现期刊
- NLM 目录全量导入（覆盖所有期刊的 ISO 缩写、出版商、学科分类）

### ✅ 期刊权重体系

`global_journals` 新增三个字段：`priority_score`、`priority_source`、`specialty`，用于综合排序和专科筛选。

**评分公式（`compute_priority_score()`）：**

| 维度 | 规则 | 最高 |
|---|---|---|
| Tier 基础分 | 1→80, 2→65, 3→50, 4→20 | 80 |
| IF 加成分 | ≥20→+15, ≥10→+10, ≥5→+5, ≥2→+2 | 15 |
| 收录量加成分 | ≥5000→+10, ≥1000→+5, ≥100→+2 | 10 |
| 专科加成分 | specialty='oncology'→+10 | 10 |

封顶 100 分。`priority_source='manual'` 的行被自动任务跳过。

**specialty 自动判定：**
- Tier 1-3 → `'oncology'`
- name ILIKE '%oncol%' OR '%cancer%' OR '%tumor%' OR '%neoplas%' → `'oncology'`
- 其余 → NULL（admin 可在管理后台补救）

**用户关注提升（查询时实时）：** `LEFT JOIN user_journal_subscriptions` → 已关注的期刊 +20 排序。

**查询排序：**
```sql
-- 未登录用户
ORDER BY priority_score DESC

-- 登录用户（关注期刊优先）
ORDER BY CASE WHEN sub.user_id IS NOT NULL THEN gj.priority_score + 20
              ELSE gj.priority_score END DESC
```
