如何使用SPARQL从三元组库检索指定SHACL形状的完整关联数据
问题背景
现有如下内容的ttl格式SHACL规则文件:
ex:Shape1 a sh:NodeShape ; sh:property ex:Property-1 rdfs:label "Shape 1" ex:Property-1 a sh:PropertyShape ; sh:path ex:property1 sh:name "Property 1" ex:property1 a owl:DatatypeProperty
将该文件加载到存储了大量SHACL形状的三元组库后,需要编写SPARQL查询完整检索上述全部关联数据。
之前尝试的查询存在两个明显问题:一是会返回三元组库中所有无关形状数据,二是无法检索到ex:property1相关的三元组,原有错误查询如下:
PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX ex: <http://example.com/#> CONSTRUCT { ?subject ?predicate ?object } WHERE { ex:Shape1 sh:property ?propertyShape . { ex:Shape1 ?predicate ?object } UNION { ?propertyShape ?predicate ?object } ?subject ?predicate ?object . }
正确SPARQL实现
使用如下CONSTRUCT查询可以精准拉取目标节点形状、其关联的所有属性形状、以及属性形状通过sh:path指向的属性定义的全部三元组,不会返回无关数据:
PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX ex: <http://example.com/#> CONSTRUCT { ?s ?p ?o } WHERE { # 指定要检索的根节点形状 VALUES ?rootShape { ex:Shape1 } # 拉取根节点形状本身的所有三元组 { BIND(?rootShape AS ?s) ?rootShape ?p ?o } UNION # 拉取根节点关联的所有属性形状的全部三元组 { ?rootShape sh:property ?propShape . BIND(?propShape AS ?s) ?propShape ?p ?o } UNION # 拉取属性形状通过sh:path指向的属性实体的全部三元组 { ?rootShape sh:property ?propShape . ?propShape sh:path ?pathProp . BIND(?pathProp AS ?s) ?pathProp ?p ?o } }
说明
- 原有查询的错误原因:
- 最后一行
?subject ?predicate ?object没有加任何范围限定,只要三元组的谓词、宾语和前面匹配到的内容重合就会被返回,直接带出全库的无关三元组。 - 没有遍历属性形状中
sh:path指向的属性实体,自然无法获取ex:property1对应的三元组。
- 最后一行
- 上述查询通过三段
UNION分别明确限定了三类需要拉取的主语范围,不会越界拉取无关数据,同时完整覆盖示例中的所有三元组。 - 注意:如果你的SHACL规则存在嵌套属性形状(比如属性形状下通过
sh:property关联子属性形状),可以把属性匹配路径改为sh:property*实现递归拉取所有层级的属性形状,再匹配对应路径属性即可。
内容的提问来源于stack exchange,提问作者agustaf
相关产品推荐
相关产品推荐

