Index per-source tag refreshes for scalable bulk ingestion
Metadata integrity checks / metadata (push) Successful in 5s

This commit is contained in:
2026-11-06 11:39:16 +08:00
parent 5d9d13a272
commit a3539be4b1
3 changed files with 17 additions and 5 deletions
+1 -1
View File
@@ -121,7 +121,7 @@ python3 -B collect_peerread.py --cache /data/paper-index/raw/http-cache \
--out /data/paper-index/collected
```
数据任务以一次性 systemd 服务运行:`paper-atlas-arxiv-import`、`paper-atlas-pmlr-collect`、`paper-atlas-peerread-collect`;`paper-atlas-pmlr-verify` 用于全索引复核,`paper-atlas-conference-merge` 用于单写入合并。它们不是定时任务。主库只允许一个写入进程;会议采集先写独立 JSONL,待 arXiv 主批次结束后再合并;也可以使用 `merge_conferences.py` 在保存断点处暂停本项目的 arXiv unit、顺序合并会议清单并恢复。该操作应作为独立的一次性 systemd 任务运行,避免 SSH 断开影响恢复;不能同时启动多个合并任务。运行日志位于 `/data/paper-index/*-import.log`、`/data/paper-index/*-collect.log`。任何服务启动成功都不等于批次已完成,需检查批次状态、清单与完整性结果。
数据任务以一次性 systemd 服务运行:`paper-atlas-arxiv-import`、`paper-atlas-pmlr-collect`、`paper-atlas-peerread-collect`;`paper-atlas-pmlr-verify` 用于全索引复核,`paper-atlas-conference-merge` 用于单写入合并。它们不是定时任务。主库只允许一个写入进程;会议采集先写独立 JSONL,待 arXiv 主批次结束后再合并;也可以使用 `merge_conferences.py` 在保存断点处暂停本项目的 arXiv unit、顺序合并会议清单并恢复。该操作应作为独立的一次性 systemd 任务运行,避免 SSH 断开影响恢复;不能同时启动多个合并任务。运行日志位于 `/data/paper-index/*-import.log`、`/data/paper-index/*-collect.log`。任何服务启动成功都不等于批次已完成,需检查批次状态、清单与完整性结果。标签按来源刷新使用 `paper_tags_source_evidence` 索引,避免每条论文都扫描整张标签表。运行中的 arXiv 可以通过同一协调脚本的 `--schema-only` 模式在断点更新索引后恢复;此模式要求已有 arXiv unit 正在运行。
## 长期维护与更新
+15 -4
View File
@@ -10,6 +10,7 @@ import subprocess
from pathlib import Path
from import_records import ingest_file
from index_core import Store
UNIT='paper-atlas-arxiv-import.service'
@@ -27,6 +28,8 @@ def merge(db,archive,files):
raise ValueError('Missing collected file or manifest: '+filename)
if not Path(archive).is_file():
raise ValueError('Missing arXiv archive')
if not Path(db).is_file():
raise ValueError('Missing existing database')
if property_value('ActiveState')!='active':
raise RuntimeError('Expected the existing arXiv unit to be active; inspect it before proceeding')
subprocess.run(['systemctl','stop',UNIT],check=True)
@@ -34,12 +37,17 @@ def merge(db,archive,files):
with sqlite3.connect(db) as c:
checkpoint=c.execute("SELECT records_written FROM ingest_runs WHERE source_id=(SELECT id FROM sources WHERE name='arxiv') ORDER BY id DESC LIMIT 1").fetchone()
print('Saved arxiv checkpoint:',checkpoint,flush=True)
schema_store=Store(db)
schema_store.conn.close()
for filename in files:
ingest_file(db,filename)
with sqlite3.connect(db) as c:
errors=c.execute('PRAGMA foreign_key_check').fetchall()
if errors:
raise RuntimeError('Foreign key violations after merge')
if files:
errors=c.execute('PRAGMA foreign_key_check').fetchall()
if errors:
raise RuntimeError('Foreign key violations after merge')
else:
print('Tag refresh plan:',c.execute('EXPLAIN QUERY PLAN DELETE FROM paper_tags WHERE source_record_id=? AND evidence_key=?',(1,'arxiv:categories')).fetchall(),flush=True)
print('Decision totals:',c.execute('SELECT status,count(*) FROM decisions GROUP BY status').fetchall(),flush=True)
finally:
if property_value('LoadState')=='loaded':
@@ -55,6 +63,9 @@ if __name__=='__main__':
parser=argparse.ArgumentParser()
parser.add_argument('--db',required=True)
parser.add_argument('--archive',required=True)
parser.add_argument('files',nargs='+')
parser.add_argument('--schema-only',action='store_true',help='Apply idempotent schema/index updates at a saved checkpoint')
parser.add_argument('files',nargs='*')
args=parser.parse_args()
if not args.files and not args.schema_only:
parser.error('Provide collected files or --schema-only')
merge(args.db,args.archive,args.files)
+1
View File
@@ -63,6 +63,7 @@ CREATE TABLE IF NOT EXISTS paper_tags (
source_record_id INTEGER REFERENCES source_records(id),
evidence_key TEXT NOT NULL, PRIMARY KEY(paper_id,tag_id,evidence_key)
);
CREATE INDEX IF NOT EXISTS paper_tags_source_evidence ON paper_tags(source_record_id,evidence_key);
CREATE TABLE IF NOT EXISTS match_candidates (
left_paper_id INTEGER NOT NULL REFERENCES papers(id), right_paper_id INTEGER NOT NULL REFERENCES papers(id),
method TEXT NOT NULL, score REAL, evidence_json TEXT NOT NULL,