Wikidata SPARQL请求报错:Headless value factory不应被请求命名空间
Wikidata地理区域数据SPARQL查询异常排查
我有一个从Wikidata提取地理区域各类数据的SPARQL请求:
SELECT DISTINCT ?h ?hLabel ?type ?location ?parent ?north ?south ?east ?west ?area WHERE { VALUES (?h) {(wd:Q1005)} ?h wdt:P31|wdt:P31/wdt:P279* ?t. BIND ( COALESCE( IF((?t= wd:Q515), 3, 1/0), #city IF((?t= wd:Q3957), 3, 1/0), # small city IF((?t= wd:Q107390),2,1/0), # federated state IF((?t= wdt:Q106458883),2,1/0), #state IF((?t= wdt:Q4835091),2,1/0), #territory IF((?t= wdt:Q3624078),1, 1/0), # sovereign state IF((?t= wdt:Q6256),1, 1/0), # country 0 ) AS ?type) OPTIONAL {?h wdt:P625 ?location} OPTIONAL {?h wdt:P1332 ?north} OPTIONAL {?h wdt:P1333 ?south} OPTIONAL {?h wdt:P1334 ?east} OPTIONAL {?h wdt:P1335 ?west} OPTIONAL {?h wdt:P2046 ?area} OPTIONAL {?h wdt:P131 ?parent} OPTIONAL {?h wdt:P276 ?parent} OPTIONAL {?h wdt:P361 ?parent} OPTIONAL {BIND(IF(wdt:P17=?h,"",wdt:P17) AS ?parent)} OPTIONAL {?h wdt:P30 ?parent} SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE]" . } } ORDER BY DESC (?type) LIMIT 1
这个查询对瑞士(wd:Q39)等多数地点运行正常,但对冈比亚(wd:Q1245)等部分地点执行失败,抛出异常:
Unknown error : Headless value factory should not be asked for its namespace
并附带Java堆栈跟踪。移除BIND(COALESCE(..))代码块后错误消失,但无法确定问题根源。
问题根源分析
非法的属性-实体比较:查询中存在一个写法错误的OPTIONAL块:
OPTIONAL {BIND(IF(wdt:P17=?h,"",wdt:P17) AS ?parent)}wdt:P17是代表“所属国家”的属性URI,而?h是地理实体URI,直接将两者比较属于非法的类型匹配,会导致Wikidata查询服务在处理值时触发内部错误。当结合COALESCE中的错误分支逻辑时,会进一步触发服务端的“Headless value factory”异常。
错误分支的兼容性问题:原查询用
1/0生成算术错误来让COALESCE跳过不匹配的类型分支,虽然符合SPARQL规范,但Wikidata的查询服务对这种错误分支的重复处理(当一个实体匹配多个?t类型时)存在兼容性bug,可能和非法比较的逻辑交互,最终触发异常。
修复后的查询
SELECT DISTINCT ?h ?hLabel ?type ?location ?parent ?north ?south ?east ?west ?area WHERE { VALUES (?h) {(wd:Q1245)} # 可替换为目标实体ID ?h wdt:P31|wdt:P31/wdt:P279* ?t. # 用VALUES定义类型映射,避免错误分支 VALUES (?t ?type) { (wd:Q515 3) # 城市 (wd:Q3957 3) # 小城市 (wd:Q107390 2) # 联邦州 (wd:Q106458883 2) # 州 (wd:Q4835091 2) # 领地 (wd:Q3624078 1) # 主权国家 (wd:Q6256 1) # 国家 } # 无匹配类型时默认设为0 OPTIONAL { BIND(0 AS ?type) } OPTIONAL {?h wdt:P625 ?location} OPTIONAL {?h wdt:P1332 ?north} OPTIONAL {?h wdt:P1333 ?south} OPTIONAL {?h wdt:P1334 ?east} OPTIONAL {?h wdt:P1335 ?west} OPTIONAL {?h wdt:P2046 ?area} OPTIONAL {?h wdt:P131 ?parent} # 所属行政区域 OPTIONAL {?h wdt:P276 ?parent} # 所在地 OPTIONAL {?h wdt:P361 ?parent} # 包含于 OPTIONAL {?h wdt:P17 ?parent} # 所属国家 OPTIONAL {?h wdt:P30 ?parent} # 所属大洲 SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE]" . } } ORDER BY DESC (?type) LIMIT 1
修复说明
- 移除了非法的属性-实体比较逻辑,将错误的
BIND(IF(wdt:P17=?h,"",wdt:P17) AS ?parent)替换为正确的属性查询OPTIONAL {?h wdt:P17 ?parent}。 - 用
VALUES映射类型替代原COALESCE中的错误分支写法,既符合SPARQL规范,又避免了服务端的异常触发。 - 保留了原查询的所有数据提取逻辑,同时解决了异常问题。
内容的提问来源于stack exchange,提问作者Dr. Goulu
相关产品推荐
相关产品推荐

