现在我有一个查询返回特定实体的各种属性列表:
SELECT ?propLabel ?val WHERE {
BIND(wd:Q122426 as ?entity)
{
BIND(?entity AS ?valUrl)
BIND("n/a" AS ?propUrl)
BIND("name"@en AS ?propLabel)
?entity rdfs:label ?val.
FILTER((LANG(?val)) = "en")
# instance of
} UNION {
?entity wdt:P31 ?valUrl .
BIND("instance of"@en AS ?propLabel)
# filter isIRI(?valUrl)
?valUrl rdfs:label ?valLabel
FILTER (LANG(?valLabel) = "en")
BIND(CONCAT(?valLabel) AS ?val)
# occupation
} UNION {
?entity wdt:P106 ?val.
BIND("occupation"@en AS ?propLabel)
# position held
} UNION {
?entity wdt:P39 ?val.
BIND("position"@en AS ?propLabel)
# ... and more ...
}
}
Run Code Online (Sandbox Code Playgroud)
这很好用,但它返回实体代码 (Qxxxxx) 而不是文本标签。所以我可以这样改变它:
# occupation
} UNION {
?entity wdt:P106 ?valUrl.
BIND("occupation"@en AS ?propLabel)
?valUrl rdfs:label ?valLabel
FILTER (LANG(?valLabel) = "en")
BIND(CONCAT(?valLabel) AS ?val)
Run Code Online (Sandbox Code Playgroud)
效果很好。
如何将多个谓词的值“折叠”为一个字符串?即对于谓词 P106、P119、Px、Py 等,得到:
| ?property | ?valueLabel |
|-------------+-------------|
| tags | politician, Giza East Field, something else, something else |
| name | Henutsen |
Run Code Online (Sandbox Code Playgroud)
是否有更有效的方法来构建查询而不是UNION对每个谓词进行查询?例如,仅提供谓词列表P31, P106, P39等
UNION这是一个用紧凑子句替换 的版本VALUES,并使用标签服务(由评论中的 AKSW 提供):
SELECT ?entity ?property ?valueLabel {\n VALUES ?entity { wd:Q122426 }\n VALUES (?p ?property) {\n (wdt:P31 "instance of"@en)\n (rdfs:label "name"@en)\n (wdt:P106 "occupation"@en)\n (wdt:P39 "position"@en)\n }\n ?entity ?p ?value\n FILTER (!isLiteral(?value) || lang(?value) = "" || langmatches(lang(?value), "en"))\n SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n结果:
\n\n| ?property | ?valueLabel |\n|-------------+-------------|\n| instance of | human |\n| occupation | politician |\n| name | Henutsen |\nRun Code Online (Sandbox Code Playgroud)\n\n将多行折叠成单行,并以逗号分隔的列表作为值,理论上也是可能的,看起来像这样:
\n\nSELECT ?entity\n (group_concat(?property; separator=", ") AS ?properties)\n (group_concat(?valueLabel; separator=", ") AS ?values)\nWHERE {\n ...\n}\nGROUP BY ?entity\nRun Code Online (Sandbox Code Playgroud)\n\n原始查询插入于...。这个想法是用于按GROUP BY实体对结果进行分组(这里并不是严格必要的,因为无论如何我们只有一个实体,但如果您想向查询添加更多实体),然后将group_concat每个实体的所有值合并为一个值。
不幸的是,由于某种原因这不起作用;?properties看起来不错,但?values里面是空的。它可能与 \xe2\x80\x9cmagic\xe2\x80\x9d 标签服务有关,也许它与聚合不兼容。
更新:这是一个将名称和 \xe2\x80\x9ctags\xe2\x80\x9d 作为单独行返回的版本,如更新的问题所示:
\n\nSELECT ?property ?valueLabel {\n {\n SELECT\n ("tags" AS ?property)\n (group_concat(?valueLabel; separator=", ") AS ?valueLabel)\n WHERE {\n VALUES ?p { wdt:P31 wdt:P106 wdt:P119 wdt:P39 }\n wd:Q122426 ?p ?value\n SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }\n }\n } UNION {\n BIND ("name"@en AS ?property)\n wd:Q122426 rdfs:label ?valueLabel\n FILTER langMatches(lang(?valueLabel), "en")\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n结果:
\n\n| ?property | ?valueLabel |\n|-----------+------------------------------------|\n| tags | human, politician, Giza East Field |\n| name | Henutsen |\nRun Code Online (Sandbox Code Playgroud)\n\n这个查询有一点有点奇怪。请注意,由标签服务分配一个值,但随后在内部子查询的子句?valueLabel中重新分配不同的值。SELECTSPARQL 中通常不允许这种重新分配,但这里实际上需要这种重新分配才能使查询正常工作。这似乎是标签服务的一个怪癖。