SPARQL:将多个谓词值组合成标签数组

T3d*_*b0t 6 sparql wikidata

现在我有一个查询返回特定实体的各种属性列表:

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

cyg*_*gri 3

UNION这是一个用紧凑子句替换 的版本VALUES,并使用标签服务(由评论中的 AKSW 提供):

\n\n
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}\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果:

\n\n
| ?property   | ?valueLabel |\n|-------------+-------------|\n| instance of | human       |\n| occupation  | politician  |\n| name        | Henutsen    |\n
Run Code Online (Sandbox Code Playgroud)\n\n

将多行折叠成单行,并以逗号分隔的列表作为值,理论上也是可能的,看起来像这样:

\n\n
SELECT ?entity\n  (group_concat(?property; separator=", ") AS ?properties)\n  (group_concat(?valueLabel; separator=", ") AS ?values)\nWHERE {\n  ...\n}\nGROUP BY ?entity\n
Run Code Online (Sandbox Code Playgroud)\n\n

原始查询插入于...。这个想法是用于按GROUP BY实体对结果进行分组(这里并不是严格必要的,因为无论如何我们只有一个实体,但如果您想向查询添加更多实体),然后将group_concat每个实体的所有值合并为一个值。

\n\n

不幸的是,由于某种原因这不起作用;?properties看起来不错,但?values里面是空的。它可能与 \xe2\x80\x9cmagic\xe2\x80\x9d 标签服务有关,也许它与聚合不兼容。

\n\n

更新:这是一个将名称和 \xe2\x80\x9ctags\xe2\x80\x9d 作为单独行返回的版本,如更新的问题所示:

\n\n
SELECT ?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}\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果:

\n\n
| ?property | ?valueLabel                        |\n|-----------+------------------------------------|\n| tags      | human, politician, Giza East Field |\n| name      | Henutsen                           |\n
Run Code Online (Sandbox Code Playgroud)\n\n

这个查询有一点有点奇怪。请注意,由标签服务分配一个值,但随后在内部子查询的子句?valueLabel中重新分配不同的值。SELECTSPARQL 中通常不允许这种重新分配,但这里实际上需要这种重新分配才能使查询正常工作。这似乎是标签服务的一个怪癖。

\n