使用SPARQL检索具有子节点的RDF资源

使用SPARQL检索具有子节点的RDF资源,sparql,rdf,Sparql,Rdf,我需要使用一个SPARQL查询检索与特定谓词标识的主题相关联的所有“属性”。我特别避免使用术语“导出三元组”,因为我不一定需要CONSTRUCT(无论CONSTRUCT还是SELCET都可以) 一些“属性”是节点本身(可能是空白节点),需要“递归”检索。谓词集是已知的(我有一个完整的谓词列表,它们都在同一个前缀中,并且都是具有该前缀的谓词)。要“递归”的谓词是它们的子集 @prefix ex: <http://example.org/ex/> . @prefix : <http

我需要使用一个SPARQL查询检索与特定谓词标识的主题相关联的所有“属性”。我特别避免使用术语“导出三元组”,因为我不一定需要
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
但是,在您的场景中有两个要求使得这更加困难:

>代码>:也应返回PRED-7/COD>值:描述通常只返回所描述的资源的空白节点闭包,因此这不是一个完整的答案。李>
  • 只应返回某些属性:
    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
    
    但是,在您的场景中有两个要求使得这更加困难:

    >代码>:也应返回PRED-7/COD>值:描述通常只返回所描述的资源的空白节点闭包,因此这不是一个完整的答案。李>
  • 只应返回某些属性:
    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的子图