如何在Wikidata SPARQL中按笔名查询人物?解决超时问题
解决Wikidata SPARQL查询笔名/艺名人物超时问题
问题分析
当查询Madonna、Cher这类短笔名/艺名时,?person rdfs:label "Madonna"@en这行代码会匹配大量非人物条目(比如同名作品、品牌等),加上后续多OPTIONAL关联和GROUP BY聚合操作,导致查询负载过高超时。而真实姓名(如Harrison Ford)匹配的条目少,查询效率自然更高。
优化方案(单次查询解决)
方案1:缩小匹配范围+覆盖别名存储
调整查询顺序,先限定人物类型,同时匹配标签和别名字段(Wikidata中P1449是别名属性,很多艺名会存在这里),减少无效匹配:
SELECT ?person ?personLabel ?birthdate (GROUP_CONCAT(DISTINCT ?occupationLabel; separator=", ") as ?occupations) ?birthPlaceLabel ?image (GROUP_CONCAT(DISTINCT ?spouseLabel; separator=", ") as ?spouses) ?familyLabel ?familyDescription ?qid WHERE { # 先过滤所有人条目,缩小后续匹配范围 ?person wdt:P31 wd:Q5. # 统一管理查询名称,同时匹配官方标签和别名 VALUES ?targetName {"Madonna"@en} { ?person rdfs:label ?targetName } UNION { ?person wdt:P1449 ?targetName } OPTIONAL { ?person wdt:P569 ?birthdate. } OPTIONAL { ?person wdt:P106 ?occupation. } OPTIONAL { ?person wdt:P19 ?birthPlace. } OPTIONAL { ?person wdt:P18 ?image. } OPTIONAL { ?person wdt:P26 ?spouse. } OPTIONAL { ?person wdt:P22 ?family. } BIND(STR(?person) AS ?qid) # 用官方标签服务统一获取多语言标签,避免手动查询rdfs:label SERVICE wikibase:label { bd:serviceParam wikibase:language "en". ?occupation rdfs:label ?occupationLabel. ?spouse rdfs:label ?spouseLabel. } } GROUP BY ?person ?personLabel ?birthdate ?birthPlaceLabel ?image ?familyLabel ?familyDescription ?qid LIMIT 1
方案2:调用Wikidata搜索API精准匹配
如果方案1仍超时,直接用Wikidata的搜索API返回最相关的匹配条目,优先命中目标人物:
SELECT ?person ?personLabel ?birthdate (GROUP_CONCAT(DISTINCT ?occupationLabel; separator=", ") as ?occupations) ?birthPlaceLabel ?image (GROUP_CONCAT(DISTINCT ?spouseLabel; separator=", ") as ?spouses) ?familyLabel ?familyDescription ?qid WHERE { # 调用Wikidata搜索接口,获取匹配的条目 SERVICE wikibase:mwapi { bd:serviceParam wikibase:api "Search". bd:serviceParam wikibase:endpoint "www.wikidata.org". bd:serviceParam mwapi:search "Madonna". bd:serviceParam mwapi:language "en". ?item wikibase:apiOutputItem mwapi:title. } # 过滤出人物类型条目 ?person wdt:P31 wd:Q5. ?person = ?item. OPTIONAL { ?person wdt:P569 ?birthdate. } OPTIONAL { ?person wdt:P106 ?occupation. } OPTIONAL { ?person wdt:P19 ?birthPlace. } OPTIONAL { ?person wdt:P18 ?image. } OPTIONAL { ?person wdt:P26 ?spouse. } OPTIONAL { ?person wdt:P22 ?family. } BIND(STR(?person) AS ?qid) SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } } GROUP BY ?person ?personLabel ?birthdate ?birthPlaceLabel ?image ?familyLabel ?familyDescription ?qid LIMIT 1
备选方案:二次查询
如果上述单次查询优化都无法解决超时问题,只能采用二次查询方案:
- 先执行简单查询获取目标人物的QID:
SELECT ?person WHERE { ?person wdt:P31 wd:Q5. VALUES ?targetName {"Madonna"@en} { ?person rdfs:label ?targetName } UNION { ?person wdt:P1449 ?targetName } } LIMIT 1
- 用获取到的QID替换查询中的
?person,执行详情查询。
内容的提问来源于stack exchange,提问作者Travis
相关产品推荐
相关产品推荐

