chore: batch commit remaining changes
Includes search engine improvements, Alembic migrations, new services (pubmed_daily_update, query_expansion), frontend updates, and documentation sync.
This commit is contained in:
+48
-11
@@ -2,7 +2,7 @@
|
||||
|
||||
## 日期时间类型规范
|
||||
|
||||
**全部使用 `TIMESTAMPTZ`**。固定日期字段(出生日期、发表日期、批准日期、排期日期)用 `DATE`。
|
||||
**TIMESTAMPTZ 为主**。纯日期字段(出生日期、发表日期、批准日期、排期日期、PubMed 纯日期字段)用 `DATE`。
|
||||
|
||||
```sql
|
||||
-- ✅ 正确
|
||||
@@ -152,6 +152,7 @@ CREATE TABLE global_literature (
|
||||
issue VARCHAR(50), -- 期号 【PubMed: Article/Journal/JournalIssue/Issue】
|
||||
pages VARCHAR(100), -- 页码 【PubMed: Article/Pagination/MedlinePgn】
|
||||
pub_date DATE, -- 纸质出版日期(期刊卷期日期,若纯电子刊则为电子日期)【PubMed: Article/Journal/JournalIssue/PubDate 组合 Year+Month+Day】
|
||||
print_date DATE, -- 纯纸质出版见刊日期(仅纸质版有值,从 PubDate 解析并经 history ppdat 校验)【PubMed: PubmedData/History/PubMedPubDate[@PubStatus="ppdat"]】
|
||||
pub_year INTEGER, -- 出版年份 【PubMed: 从 PubDate/Year 提取】
|
||||
pub_types JSONB NOT NULL DEFAULT '[]', -- 出版类型列表 【PubMed: Article/PublicationTypeList/PublicationType】
|
||||
mesh_headings JSONB NOT NULL DEFAULT '[]', -- MeSH 标引词列表(含 DescriptorName+QualifierName)【PubMed: MeshHeadingList/MeshHeading】
|
||||
@@ -160,7 +161,7 @@ CREATE TABLE global_literature (
|
||||
pmc_id VARCHAR(20), -- PMC ID(PMC1234567)【PubMed: ArticleId[@IdType="pmc"]】
|
||||
is_oa BOOLEAN NOT NULL DEFAULT FALSE, -- 是否开放获取【根据 pmc_id 或 PMC OA API 判定,非 PubMed 原始字段】
|
||||
keywords JSONB NOT NULL DEFAULT '[]', -- 作者关键词 【PubMed: Article/KeywordList/Keyword】
|
||||
pubmed_revised TIMESTAMPTZ, -- PubMed 数据库修订日期(NLM 说明不可靠)【PubMed: MedlineCitation/DateRevised】
|
||||
pubmed_revised DATE, -- PubMed 数据库修订日期(NLM 说明不可靠)【PubMed: MedlineCitation/DateRevised】
|
||||
grants JSONB NOT NULL DEFAULT '[]', -- 基金资助信息 【PubMed: Article/GrantList/Grant】
|
||||
cited_by_count INTEGER NOT NULL DEFAULT 0, -- 被引次数 【来自 NCBI elink 接口 pubmed_pubmed_citedin,非 PMID 固定字段】
|
||||
full_text_sections JSONB, -- PMC OA 全文结构化段落【来自 PMC OA Service API JATS XML,非 PubMed EFetch】
|
||||
@@ -169,7 +170,8 @@ CREATE TABLE global_literature (
|
||||
study_design JSONB, -- 研究设计分类 {primary: "RCT", sub: "Phase 3", design: "parallel"}(AI 推断,非 PubMed 原始字段)
|
||||
pico JSONB, -- PICO 结构化抽取(AI 推断,非 PubMed 原始字段)
|
||||
citation_status VARCHAR(20), -- MedlineCitation 状态 【PubMed: MedlineCitation/@Status 属性,如 "MEDLINE"/"PubMed-not-MEDLINE"/"In-Data-Review"】
|
||||
date_completed TIMESTAMPTZ, -- MeSH 标引完成日期 【PubMed: MedlineCitation/DateCompleted】
|
||||
date_completed DATE, -- NLM 整条编目记录完成日(含 MeSH 标引在内的全部处理完成)
|
||||
meshed_date DATE, -- MeSH 数据版本日期。通常=date_completed(MeSH 是编目最后一步,两者同天)。年更刷新后=新的 date_completed。NULL=无MeSH(in-process/publisher)。NOT datetime.now()
|
||||
retracted BOOLEAN NOT NULL DEFAULT FALSE, -- 是否已撤稿【依据 PubMed: Article/PublicationTypeList/PublicationType[.="Retracted Publication"]】
|
||||
retraction_details JSONB, -- 撤稿详情(关联撤稿文献等)【PubMed: CommentsCorrectionsList/CommentsCorrections[@RefType="retractionof"/"retractionin"]】
|
||||
license_info JSONB, -- 许可证信息(来自 PMC OA XML 或出版商元数据,非 PubMed 原始字段)
|
||||
@@ -180,10 +182,15 @@ CREATE TABLE global_literature (
|
||||
negative_result_details JSONB, -- 阴性结果详情(AI 抽取,非 PubMed 原始字段)
|
||||
ai_summary JSONB, -- AI 摘要(内部,非 PubMed 字段)
|
||||
chemical_list JSONB NOT NULL DEFAULT '[]', -- 化学物质列表 【PubMed: ChemicalList/Chemical】
|
||||
investigators JSONB NOT NULL DEFAULT '[]', -- 研究者列表 [{family,given,affiliation,identifiers}] 【PubMed: InvestigatorList/Investigator】
|
||||
personal_name_subjects JSONB NOT NULL DEFAULT '[]', -- 作为主题的人名 [{family,given}] 【PubMed: PersonalNameSubjectList/PersonalNameSubject】
|
||||
publication_notes JSONB NOT NULL DEFAULT '[]', -- 出版注释列表 ["note1","note2"] 【PubMed: PubmedData/PublicationNote】
|
||||
gene_symbols JSONB NOT NULL DEFAULT '[]', -- 基因符号列表 【PubMed: SupplMeshList/SupplMeshName;部分来自 Gene Symbol 或 ChemicalList】
|
||||
num_refs INTEGER, -- 参考文献数量(来自 PMC 全文或解析,非 PubMed EFetch 原始字段)
|
||||
publication_status VARCHAR(30), -- 出版状态 【PubMed: PubmedData/PublicationStatus,取值 epublish/ppublish/aheadofprint】
|
||||
article_date DATE, -- 电子出版日期(先于印刷版)【PubMed: Article/ArticleDate】
|
||||
create_date DATE, -- PubMed 记录创建日期(纯日期,无需时间)【PubMed: PubmedData/History/PubMedPubDate[@PubStatus="pubmed"] / MedlineCitation/DateCreated】
|
||||
entrez_date DATE, -- PubMed 收录日期(纯日期,无需时间)【PubMed: PubmedData/History/PubMedPubDate[@PubStatus="entrez"]】
|
||||
databank_list JSONB NOT NULL DEFAULT '[]', -- 数据库引用列表(如 ClinicalTrials.gov)【PubMed: Article/DataBankList/DataBank】
|
||||
suppl_mesh_list JSONB NOT NULL DEFAULT '[]', -- 补充 MeSH 词列表(含物质名)【PubMed: SupplMeshList/SupplMeshName】
|
||||
source VARCHAR(30) NOT NULL DEFAULT 'pubmed_ftp', -- 数据来源(内部追踪用:pubmed_api/pubmed_ftp,非 PubMed 字段)
|
||||
@@ -197,16 +204,30 @@ CREATE INDEX idx_gl_journal_iso ON global_literature(journal_iso);
|
||||
CREATE INDEX idx_gl_created ON global_literature(created_at);
|
||||
CREATE INDEX idx_gl_pmc_id ON global_literature(pmc_id);
|
||||
CREATE INDEX idx_gl_search_tsv ON global_literature USING gin(search_tsv);
|
||||
CREATE INDEX ix_gl_doi ON global_literature(doi);
|
||||
CREATE INDEX ix_gl_language ON global_literature(language);
|
||||
CREATE INDEX ix_gl_retracted ON global_literature(retracted);
|
||||
CREATE INDEX ix_gl_pub_types_gin ON global_literature USING gin(pub_types);
|
||||
CREATE INDEX ix_gl_study_design_gin ON global_literature USING gin(study_design);
|
||||
CREATE INDEX ix_gl_grants_gin ON global_literature USING gin(grants);
|
||||
CREATE INDEX ix_gl_chemical_list_gin ON global_literature USING gin(chemical_list);
|
||||
CREATE INDEX ix_gl_citation_status ON global_literature(citation_status); -- 筛选:MEDLINE only
|
||||
CREATE INDEX ix_gl_is_oa ON global_literature(is_oa); -- 筛选:Free full text
|
||||
CREATE INDEX ix_gl_is_negative ON global_literature(is_negative_result); -- 筛选:阴性结果
|
||||
CREATE INDEX ix_gl_is_preprint ON global_literature(is_preprint); -- 筛选:Exclude preprints
|
||||
CREATE INDEX ix_gl_mesh_headings ON global_literature USING gin(mesh_headings); -- 筛选:Species/Sex/Age JSONB @> 查询
|
||||
CREATE INDEX ix_global_literature_journal_iso_trgm ON global_literature USING gin(journal_iso gin_trgm_ops); -- PubMed [TA] ILIKE 兜底
|
||||
```
|
||||
|
||||
> 预估值:约 600 万条(PubMed 中肿瘤相关的历史累积),单表不需要分区
|
||||
|
||||
**全文搜索:**
|
||||
> `search_tsv`(`TSVECTOR` 类型,GIN 索引 `ix_gl_search_tsv`)由 PG 触发器自动维护,包含 **title + abstract + authors.family + authors.affiliation**。所有搜索(普通搜索 `field="all"` 和高级搜索字段选择中的作者/机构)均走 tsvector `@@` `plainto_tsquery()`,ILIKE 仅作为兜底(NULL tsvector 记录)。触发器 `trg_global_literature_tsv` 在 INSERT 或 UPDATE title/abstract 时触发重建。千万级无压力。
|
||||
> `search_tsv`(`TSVECTOR` 类型,GIN 索引 `ix_gl_search_tsv`)由 PG 触发器 `trg_global_literature_tsv` 自动维护。使用 `setweight()` 区分字段权重:**title=A 权重、abstract=B 权重、authors.family=A 权重**。所有搜索(普通搜索 `field="all"` 和高级搜索字段选择中的作者/机构)均走 tsvector `@@` `plainto_tsquery()`,ILIKE 仅作为兜底(NULL tsvector 记录)。触发器在 INSERT 或 UPDATE title/abstract/authors 时触发重建。千万级无压力。
|
||||
>
|
||||
> > **GIN 索引重建说明:** 迁移 `f80dca5baa02`(add_pico_column_to_review_literatures)的 `upgrade()` 误将 `ix_gl_search_tsv` 删除后未重建,导致所有 tsvector 搜索走全表扫描。迁移 `0314f4d28728`(rebuild_search_tsv_gin_index)已修复,紧跟在 `e341edea85e2` 之后。
|
||||
|
||||
**日期字段说明:** `pub_date`(印刷/电子出版日期)+ `article_date`(电子出版日期,实际上线时间)+ `date_completed`(MeSH 标引完成日,检索质量控制用)+ `pubmed_revised`(NLM 定义为不可靠)+ `publication_status`(epublish / ppublish / aheadofprint 出版阶段标识)。
|
||||
**日期字段说明:** `pub_date`([DP] 出版日期 = LEAST(EPDAT, PPDAT))由 `article_date`([EPDAT] 电子出版日期)+ `print_date`([PPDAT] 纸质出版日期)的最小值计算得出。`create_date`([CRDT] PubMed 记录创建日期)+ `entrez_date`([EDAT] PubMed 入库日期)+ `date_completed`(NLM 整条编目记录完成日,含 MeSH 在内的全部处理完成,实践中作为 [MHDA] 近似值)。`meshed_date` 是系统内部字段,记录 MeSH 数据的版本日期:通常=`date_completed`(MeSH 是编目最后一步,两者同天);年更刷新后设为新的 `date_completed`。NULL=无 MeSH。`pubmed_revised`(NLM 定义为不可靠)。`publication_status`(epublish / ppublish / aheadofprint 出版阶段标识)。
|
||||
> **注意:** `create_date`、`entrez_date`、`date_completed`、`meshed_date`、`pubmed_revised` 五个字段原为 TIMESTAMPTZ,现统一为 DATE 类型。原因是 NLM 所有日期来源(DateCompleted、History/PubMedPubDate、DateRevised、ArticleDate、DateCreated)仅提供 Y/M/D,无时间分量。DATE 类型更精确地反映语义,减少存储开销。
|
||||
|
||||
**PubMed 对应 XML 结构速查:**
|
||||
|
||||
@@ -223,24 +244,35 @@ CREATE INDEX idx_gl_search_tsv ON global_literature USING gin(search_tsv);
|
||||
| `volume` | `Article/Journal/JournalIssue/Volume` | 卷 |
|
||||
| `issue` | `Article/Journal/JournalIssue/Issue` | 期 |
|
||||
| `pages` | `Article/Pagination/MedlinePgn` | 页码范围 |
|
||||
| `pub_date` | `Article/Journal/JournalIssue/PubDate` | 仅取 Year/Month/Day 组合 |
|
||||
| `pub_date` | `Article/Journal/JournalIssue/PubDate` 取 Year/Month/Day 组合,与 print_date/articledate LEAST 计算 | [DP] 出版日期 = COALESCE(LEAST(EPDAT, PPDAT), 任一可用值) |
|
||||
| `print_date` | `PubmedData/History/PubMedPubDate[@PubStatus="ppdat"]` 或 `Journal/JournalIssue/PubDate` | [PPDAT] 纸质出版日期 |
|
||||
| `pub_year` | `PubDate/Year` | 单独提取年份 |
|
||||
| `pub_types` | `Article/PublicationTypeList/PublicationType` | 可多个,含 "Retracted Publication" |
|
||||
| `mesh_headings` | `MeshHeadingList/MeshHeading` | DescriptorName(UI) + QualifierName(UI) |
|
||||
| `language` | `Article/Language` | 2-3 字母 ISO 语言码 |
|
||||
| `pmc_id` | `ArticleId[@IdType="pmc"]` | 带 "PMC" 前缀 |
|
||||
| `keywords` | `Article/KeywordList/Keyword` | 作者关键词(非 MeSH) |
|
||||
| `pubmed_revised` | `MedlineCitation/DateRevised` | 不可靠,不应视为修订依据 |
|
||||
| `pubmed_revised` | `MedlineCitation/DateRevised` | 不可靠,不应视为修订依据。仅 Year/Month/Day,DATE 类型 |
|
||||
| `grants` | `Article/GrantList/Grant` | GrantID + Agency + Country |
|
||||
| `chemical_list` | `ChemicalList/Chemical` | RegistryNumber + NameOfSubstance(UI) |
|
||||
| `suppl_mesh_list` | `SupplMeshList/SupplMeshName` | 补充概念词 |
|
||||
| `databank_list` | `Article/DataBankList/DataBank` | DataBankName + AccessionNumberList |
|
||||
| `trial_reg` | `Article/DataBankList/DataBank` | 从中提取 NCT/EudraCT/ChiCTR |
|
||||
| `citation_status` | `MedlineCitation/@Status` | "MEDLINE","PubMed-not-MEDLINE","In-Data-Review","PubMed" |
|
||||
| `date_completed` | `MedlineCitation/DateCompleted` | MeSH 标引完成日 |
|
||||
| `retraction_details` | `CommentsCorrectionsList/CommentsCorrections[@RefType="retractionof" or "retractionin"]` | 撤稿关联关系 |
|
||||
| `date_completed` | `MedlineCitation/DateCompleted` | NLM 整条编目记录完成日(含 MeSH 标引在内的全部处理完成)。实践中作为 [MHDA] 近似值使用。仅 Year/Month/Day,DATE 类型 |
|
||||
| `meshed_date` | 系统内部字段 | MeSH 数据版本日期。通常=date_completed(MeSH 是编目最后一步,两者同天)。年更后=新的 date_completed。NULL=无MeSH。DATE 类型 |
|
||||
| `publication_status` | `PubmedData/PublicationStatus` | "epublish" / "ppublish" / "aheadofprint" |
|
||||
| `article_date` | `Article/ArticleDate` | 电子出版日期(印刷版之前的日期)|
|
||||
| `article_date` | `Article/ArticleDate` | [EPDAT] 电子出版日期(印刷版之前的日期)|
|
||||
| `create_date` | `PubmedData/History/PubMedPubDate[@PubStatus="pubmed"]` 或 `MedlineCitation/DateCreated` | [CRDT] PubMed 记录创建日期。仅 Year/Month/Day,DATE 类型 |
|
||||
| `entrez_date` | `PubmedData/History/PubMedPubDate[@PubStatus="entrez"]` | [EDAT] PubMed 收录日期。仅 Year/Month/Day,DATE 类型 |
|
||||
| `pharmacological_actions` | `MedlineCitation/ChemicalList/PharmacologicalAction/NameOfSubstance` | [PA] 药理作用 [{name, ui}] |
|
||||
| `cois_statement` | `Article/CoiStatement` | [COIS] 利益冲突声明 |
|
||||
| `vernacular_title` | `Article/VernacularTitle` | [TT] 非英文标题的拉丁转写 |
|
||||
| `is_preprint` | DOI prefix + journal name 检测 | 是否为预印本(非 PubMed 原始字段) |
|
||||
| `auid_data` | `Author/Identifier[Source="ORCID"]` | [AUID] 作者标识符 [{type, value, author_index}] |
|
||||
| `investigators` | `InvestigatorList/Investigator` | [IR] 多中心试验研究者 [{family, given, affiliation, identifiers}] |
|
||||
| `personal_name_subjects` | `PersonalNameSubjectList/PersonalNameSubject` | [PS] 作为主题的人名 [{family, given}] |
|
||||
| `publication_notes` | `PubmedData/PublicationNote` | [PUBN] 出版注释列表 |
|
||||
|
||||
### 2.2 global_tags — 肿瘤科标签树
|
||||
|
||||
@@ -254,6 +286,9 @@ CREATE TABLE global_tags (
|
||||
level INTEGER NOT NULL DEFAULT 1, -- 层级深度
|
||||
parent_id UUID REFERENCES global_tags(id) ON DELETE CASCADE, -- 父标签ID
|
||||
tree_number VARCHAR(100), -- MeSH 树编号
|
||||
entry_terms JSONB, -- MeSH 入口词列表(~200k,NLM desc2025.asc 导入,用于 ATM 自动术语映射)
|
||||
source VARCHAR(20) DEFAULT 'auto', -- 数据来源:manual(手工)/mesh(C04批量)/auto(管道懒创建)
|
||||
is_active BOOLEAN DEFAULT FALSE, -- 是否已确认(True=用户可见,False=仅后台可见)
|
||||
tag_category VARCHAR(30) NOT NULL DEFAULT 'cancer', -- 标签分类
|
||||
sort_order INTEGER DEFAULT 0, -- 排序序号
|
||||
icon VARCHAR(50), -- 图标名
|
||||
@@ -713,7 +748,7 @@ CREATE TABLE ai_provider_config (
|
||||
```sql
|
||||
CREATE TABLE pipeline_runs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 运行ID
|
||||
run_type VARCHAR(20) NOT NULL, -- 运行类型:daily/weekly/manual
|
||||
run_type VARCHAR(20) NOT NULL, -- 运行类型:daily_ftp_update / baseline_import / daily_citation_update / manual_full / etc.
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'running', -- 状态:running/completed/failed
|
||||
files_processed INTEGER DEFAULT 0, -- 处理文件数
|
||||
articles_total INTEGER DEFAULT 0, -- 总文献数
|
||||
@@ -724,6 +759,8 @@ CREATE TABLE pipeline_runs (
|
||||
users_matched INTEGER DEFAULT 0, -- 匹配用户数
|
||||
feeds_generated INTEGER DEFAULT 0, -- 生成 Feed 数
|
||||
error_log TEXT, -- 错误日志
|
||||
processed_date DATE, -- FTP 增量检查点:已处理的 EDAT 日期(2026-07-25 新增)
|
||||
metadata JSON, -- 扩展元数据(基线年份、文件序号范围等)(2026-07-25 新增)
|
||||
started_at TIMESTAMPTZ, -- 开始时间
|
||||
completed_at TIMESTAMPTZ, -- 完成时间
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now() -- 创建时间
|
||||
|
||||
Reference in New Issue
Block a user