现在我有一个查询,该查询返回特定实体的各种属性的列表:
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 ...
}
}
这很好用,但是它返回实体代码(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)
那很好用。
如何将多个谓词的值“折叠”为字符串?即谓词P106,P119,Px,Py等获得:
| ?property | ?valueLabel |
|-------------+-------------|
| tags | politician, Giza East Field, something else, something else |
| name | Henutsen |
有没有比UNION
构造每个谓词更有效的方法来构造查询?例如,仅提供谓词P31, P106, P39
等的列表
答案 0 :(得分:1)
这是一个用紧凑的UNION
子句代替VALUES
并使用label service(由AKSW表示感谢)的版本:
SELECT ?entity ?property ?valueLabel {
VALUES ?entity { wd:Q122426 }
VALUES (?p ?property) {
(wdt:P31 "instance of"@en)
(rdfs:label "name"@en)
(wdt:P106 "occupation"@en)
(wdt:P39 "position"@en)
}
?entity ?p ?value
FILTER (!isLiteral(?value) || lang(?value) = "" || langmatches(lang(?value), "en"))
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}
结果:
| ?property | ?valueLabel |
|-------------+-------------|
| instance of | human |
| occupation | politician |
| name | Henutsen |
理论上也可以将多行折叠为单行,并以逗号分隔的列表作为值,并且看起来像这样:
SELECT ?entity
(group_concat(?property; separator=", ") AS ?properties)
(group_concat(?valueLabel; separator=", ") AS ?values)
WHERE {
...
}
GROUP BY ?entity
,原始查询插入...
。这个想法是使用GROUP BY
来按实体对结果进行分组(这里并不是绝对必要的,因为我们毕竟只有一个实体,但是如果您想向查询中添加更多实体),然后使用group_concat
将每个实体的所有值合并为一个值。
不幸的是,由于某种原因,这不起作用; ?properties
看起来不错,但?values
为空。它可能与“魔术”标签服务有关,也许与聚合不兼容。
更新:这是一个将名称和“标签”作为单独的行返回的版本,如更新后的问题:
SELECT ?property ?valueLabel {
{
SELECT
("tags" AS ?property)
(group_concat(?valueLabel; separator=", ") AS ?valueLabel)
WHERE {
VALUES ?p { wdt:P31 wdt:P106 wdt:P119 wdt:P39 }
wd:Q122426 ?p ?value
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}
} UNION {
BIND ("name"@en AS ?property)
wd:Q122426 rdfs:label ?valueLabel
FILTER langMatches(lang(?valueLabel), "en")
}
}
结果:
| ?property | ?valueLabel |
|-----------+------------------------------------|
| tags | human, politician, Giza East Field |
| name | Henutsen |
关于此查询,有些事情有些奇怪。请注意,标签服务为?valueLabel
分配了一个值,但随后在内部子查询的SELECT
子句中重新分配了一个不同的值。 SPARQL通常不允许这种重新分配,但实际上需要才能使查询正常工作。标签服务似乎有点奇怪。