使用SPARQL检索具有子节点的RDF资源
我需要使用一个SPARQL查询检索与特定谓词标识的主题相关联的所有“属性”。我特别避免使用术语“导出三元组”,因为我不一定需要使用SPARQL检索具有子节点的RDF资源,sparql,rdf,Sparql,Rdf,我需要使用一个SPARQL查询检索与特定谓词标识的主题相关联的所有“属性”。我特别避免使用术语“导出三元组”,因为我不一定需要CONSTRUCT(无论CONSTRUCT还是SELCET都可以) 一些“属性”是节点本身(可能是空白节点),需要“递归”检索。谓词集是已知的(我有一个完整的谓词列表,它们都在同一个前缀中,并且都是具有该前缀的谓词)。要“递归”的谓词是它们的子集 @prefix ex: <http://example.org/ex/> . @prefix : <http
CONSTRUCT
(无论CONSTRUCT
还是SELCET
都可以)
一些“属性”是节点本身(可能是空白节点),需要“递归”检索。谓词集是已知的(我有一个完整的谓词列表,它们都在同一个前缀中,并且都是具有该前缀的谓词)。要“递归”的谓词是它们的子集
@prefix ex: <http://example.org/ex/> .
@prefix : <http://example.org/> .
ex:toExport
a ex:SomeClass ; # to retrieve, as in rdf: namespace
:pred-1 "Some value" ; # to retrieve "as is"
:pred-2 42 ; # to retrieve "as is"
:pred-3 [ # blank-node to be retrieved as a whole
:pred-1 "..." ;
:pred-2 1024
] ;
:pred-4 [
:pred-3 [ # "sub" blank-node to be retrieved as a whole
:pred-1 "..." ;
:pred-2 1024
]
] ;
:pred-5 [ # same for a "sub-list"
:pred-6 ( ex:something ex:else )
] ;
:pred-7 ex:subOne . # "sub-property" can be a non-blank node...
ex:subOne # ...defined as a resource of its own
:pred-1 "Value" ;
:pred-2 0 .
谓词集类似于20个不同的谓词,因此以某种方式列出它们是可以管理的,但如果是以组合的方式列出它们,则不可行。专门针对正则表达式:如果您的目标是简单地使其更易于阅读,则可以按照以下思路进行操作:
FILTER(STRSTARTS(STR(?p), STR(rdf:)) || STRSTARTS(STR(?p), STR(shacl:)))
这样,您就不必使用带有完整名称空间IRIs的长正则表达式,而且还可以将逻辑OR从正则表达式中移出,放入SPARQL过滤器逻辑本身(这可能更有效)
除此之外,我并没有立即在单个SPARQL查询中找到一种简单的方法来改进这一点。然而,如果您愿意妥协并对结果进行一些后处理,您可以通过一个简单得多的查询获得非常接近的结果
通常,使用一个简单的descripe
查询可以很好地解决这类问题:
DESCRIBE ex:toExport
但是,在您的场景中有两个要求使得这更加困难:
descripe
通常返回所有属性李>
对于第一个问题,我们可以扩展descripe
查询以更接近您的预期结果。例如,我们可以修改它,不仅描述ex:toExport
,而且还描述通过所需属性之一连接到ex:toExport
的所有资源?x
:
DESCRIBE ex:toExport ?x
WHERE {
ex:toExport ?p ?x .
FILTER(isIRI(?x))
FILTER(STRSTARTS(STR(?p), STR(rdf:)) || STRSTARTS(STR(?p), STR(shacl:)))
}
此结果将检索您想要的所有数据,但仍然无法解决问题2:它不会将返回的属性限制为您期望的属性,而是将返回ex:toExport
和?x
的所有属性
当然,过滤掉那些不需要的属性可以在后处理中完成,但这是否适合您的场景取决于数据中“不需要的”属性的数量
最后一个警告是:
descripe
查询的确切结果取决于实现。大多数实现都返回某种形式的空白节点闭包,但也有一些变化。检查SPARQL引擎的文档(或对其进行测试以了解其功能) 专门针对正则表达式:如果您的目标只是让它更易于阅读,您可以按照以下思路做一些事情:
FILTER(STRSTARTS(STR(?p), STR(rdf:)) || STRSTARTS(STR(?p), STR(shacl:)))
这样,您就不必使用带有完整名称空间IRIs的长正则表达式,而且还可以将逻辑OR从正则表达式中移出,放入SPARQL过滤器逻辑本身(这可能更有效)
除此之外,我并没有立即在单个SPARQL查询中找到一种简单的方法来改进这一点。然而,如果您愿意妥协并对结果进行一些后处理,您可以通过一个简单得多的查询获得非常接近的结果
通常,使用一个简单的descripe
查询可以很好地解决这类问题:
DESCRIBE ex:toExport
但是,在您的场景中有两个要求使得这更加困难:
descripe
通常返回所有属性李>
对于第一个问题,我们可以扩展descripe
查询以更接近您的预期结果。例如,我们可以修改它,不仅描述ex:toExport
,而且还描述通过所需属性之一连接到ex:toExport
的所有资源?x
:
DESCRIBE ex:toExport ?x
WHERE {
ex:toExport ?p ?x .
FILTER(isIRI(?x))
FILTER(STRSTARTS(STR(?p), STR(rdf:)) || STRSTARTS(STR(?p), STR(shacl:)))
}
此结果将检索您想要的所有数据,但仍然无法解决问题2:它不会将返回的属性限制为您期望的属性,而是将返回ex:toExport
和?x
的所有属性
当然,过滤掉那些不需要的属性可以在后处理中完成,但这是否适合您的场景取决于数据中“不需要的”属性的数量
最后一个警告是:
descripe
查询的确切结果取决于实现。大多数实现都返回某种形式的空白节点闭包,但也有一些变化。检查SPARQL引擎的文档(或对其进行测试以了解其功能) 我认为优化它的潜力不大,但至少可以在单独的子选择查询中首先查询不同的属性,这样它只执行一次。查询的其余部分与预期的一样,深度为3I的子图的生成没有太大的优化潜力,但您至少可以在单独的子选择查询中首先查询不同的属性,以便只执行一次。查询的其余部分与预期一样,生成深度为3的子图