feat: PubMed搜索合规审计 Phase 5-7 全部修复
P1-2: [SB][STAT][UID][DEP][MESH]字段支持 P1-4: [MH:noexp]解析+抑制树展开 P3: 前端date_to/P3-1、CJK高亮/P3-3、extractPlainText/P3-4、precision_mode移除/P3-6、loadMore sort/P3-5 P4-1: 词数上限50→100 P4-2: retracted参数清理
This commit is contained in:
@@ -23,7 +23,7 @@ from dataclasses import dataclass, field
|
||||
from enum import Enum, auto
|
||||
|
||||
# ─── 查询复杂度限制 ───
|
||||
MAX_TERMS = 50 # 与 API 层 check_query_complexity 的 50 词限制对齐
|
||||
MAX_TERMS = 100 # P4-1: 放宽到 100 词(原 50 词)
|
||||
MAX_PAREN_DEPTH = 10 # 括号嵌套最深层数
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ _FIELD_TAG_MAP: dict[str, str] = {
|
||||
"LAU": "author",
|
||||
"TW": "all",
|
||||
"OT": "all",
|
||||
"MESH": "MH", # P1-2: [MESH] 是 [MH] 的别名
|
||||
# 新增标量字段
|
||||
"LA": "language",
|
||||
"VI": "volume",
|
||||
@@ -55,23 +56,30 @@ _SPECIAL_FIELDS = {
|
||||
"MH", "MAJR", "PT", "DP", "PMID", "DOI",
|
||||
# 日期字段
|
||||
"EDAT", "CRDT", "MHDA", "LR", "DCOM",
|
||||
# P1-2: 电子出版日期
|
||||
"DEP",
|
||||
# JSONB 字段
|
||||
"GR", "SH", "RN", "NM", "SI", "PA",
|
||||
# 待补充抽取的字段(标记为特殊以便未来实现)
|
||||
"AUID", "COIS", "ED", "IR", "PS", "PUBN", "TT",
|
||||
# P1-2: 新字段
|
||||
"SB", "STAT", "UID",
|
||||
}
|
||||
|
||||
# 支持日期范围语法的字段
|
||||
_DATE_RANGE_FIELDS = {"DP", "EDAT", "CRDT", "MHDA", "LR", "DCOM"}
|
||||
_DATE_RANGE_FIELDS = {"DP", "EDAT", "CRDT", "MHDA", "LR", "DCOM", "DEP"}
|
||||
|
||||
# 所有合法字段标签(PubMed 全量字段)
|
||||
# P1-1: 移除了 BOOK/FILTER/ISBN(未实现,降级为 plain text 不如报错透明)
|
||||
_ALL_FIELD_TAGS = {
|
||||
"AB", "AD", "AU", "CN", "FAU", "AUID", "LAU", "COIS",
|
||||
"DCOM", "CRDT", "EDAT", "MHDA", "LR", "DP", "DOI",
|
||||
"DEP", # P1-2: Date of Electronic Publication
|
||||
"RN", "ED", "GR", "IR", "IP",
|
||||
"TA", "JT", "LA", "LID", "MAJR", "SH", "MH", "MH:NOEXP", "OT", "PG",
|
||||
"PA", "PT", "PMID", "PUBN", "SI", "PS", "NM", "TW",
|
||||
"SB", "STAT", "UID", # P1-2: Subset, Status, UID
|
||||
"MESH", # P1-2: [MH] 别名
|
||||
"TI", "TIAB", "TT", "VI",
|
||||
}
|
||||
|
||||
@@ -187,6 +195,8 @@ class ParsedPubmedQuery:
|
||||
lr_to: str | None = None
|
||||
dcom_from: str | None = None # [DCOM]
|
||||
dcom_to: str | None = None
|
||||
dep_from: str | None = None # P1-2: [DEP]
|
||||
dep_to: str | None = None
|
||||
# 特殊字段(存储 Term 以保留 is_not 标志)
|
||||
mesh_terms: list[Term] = field(default_factory=list) # [MH] (was list[str])
|
||||
majr_terms: list[Term] = field(default_factory=list) # [MAJR] (was list[str])
|
||||
@@ -207,6 +217,9 @@ class ParsedPubmedQuery:
|
||||
auid_terms: list[Term] = field(default_factory=list) # [AUID]
|
||||
cois_terms: list[Term] = field(default_factory=list) # [COIS]
|
||||
tt_terms: list[Term] = field(default_factory=list) # [TT]
|
||||
sb_terms: list[Term] = field(default_factory=list) # P1-2: [SB] Subset
|
||||
stat_terms: list[Term] = field(default_factory=list) # P1-2: [STAT] Status
|
||||
uid_terms: list[Term] = field(default_factory=list) # P1-2: [UID] PMID/DOI 统一
|
||||
plain_terms: list[Term] = field(default_factory=list) # no field tag
|
||||
boolean_operator: str = "and" # "and" | "or" | "mixed"
|
||||
has_not: bool = False # contains NOT
|
||||
@@ -349,6 +362,8 @@ class PubmedQueryParser:
|
||||
pass
|
||||
elif term.field == "__RANGE_DCOM__":
|
||||
pass
|
||||
elif term.field == "__RANGE_DEP__":
|
||||
pass
|
||||
elif term.field == "ED":
|
||||
result.ed_terms.append(term)
|
||||
elif term.field == "IR":
|
||||
@@ -363,6 +378,12 @@ class PubmedQueryParser:
|
||||
result.cois_terms.append(term)
|
||||
elif term.field == "TT":
|
||||
result.tt_terms.append(term)
|
||||
elif term.field == "SB":
|
||||
result.sb_terms.append(term)
|
||||
elif term.field == "STAT":
|
||||
result.stat_terms.append(term)
|
||||
elif term.field == "UID":
|
||||
result.uid_terms.append(term)
|
||||
else:
|
||||
result.plain_terms.append(term)
|
||||
|
||||
@@ -494,6 +515,7 @@ class PubmedQueryParser:
|
||||
"MHDA": ("mhda_from", "mhda_to", None, None, "__RANGE_MHDA__"),
|
||||
"LR": ("lr_from", "lr_to", None, None, "__RANGE_LR__"),
|
||||
"DCOM": ("dcom_from", "dcom_to", None, None, "__RANGE_DCOM__"),
|
||||
"DEP": ("dep_from", "dep_to", None, None, "__RANGE_DEP__"), # P1-2
|
||||
}
|
||||
date_attr, date_attr_to, yr_from_attr, yr_to_attr, marker_field = attr_map[field]
|
||||
# 反向范围自动交换(如 2026:2024[DP] → 2024:2026[DP])
|
||||
|
||||
Reference in New Issue
Block a user