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

时间:2016-08-15 18:25:25

标签: sparql rdf

我需要检索所有"属性"使用一个SPARQL查询与特定谓词标识的主题相关联。我特别避免使用条款"导出三元组",因为我不一定需要CONSTRUCTCONSTRUCTSELCET可以这样做。)

一些"属性"节点本身(可能是空白节点),并且需要递归地#34;检索。谓词集是已知的(我有一个全面的列表,它们都在相同的前缀中,并且它们都是具有该前缀的那些)。谓词"递归"结束是他们的一部分。

@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 .

在上面的示例中,我需要使用谓词:pred-1:pred-2(简单值):pred-3检索三元组(其值为具有2个三元组的空白节点)在这些例子中),:pred-4(一个空白节点本身,有一个额外的空白节点),等等。:pred-7很有意思,因为它显示了所有&#34;子节点&#34;不一定是空白节点。

以下查询是我发现的最接近我的要求的查询,但它使用了IRI的字符串值的正则表达式,我希望避免对大型数据集的查询:

CONSTRUCT {
    ?s  ?p   ?o .
    ?o  ?pp  ?oo .
    ?oo ?ppp ?ooo .
}
WHERE {
{
    ?s ?p ?o .
    FILTER ( regex(str(?p), "^(http://www.w3.org/ns/shacl#|http://www.w3.org/1999/02/22-rdf-syntax-ns#)") )
    OPTIONAL
    {
        ?o ?pp ?oo .
        FILTER ( regex(str(?pp), "^(http://www.w3.org/ns/shacl#|http://www.w3.org/1999/02/22-rdf-syntax-ns#)") )
        OPTIONAL
        {
            ?oo ?ppp ?ooo .
            FILTER ( regex(str(?ppp), "^(http://www.w3.org/ns/shacl#|http://www.w3.org/1999/02/22-rdf-syntax-ns#)") )
        }
    }
}

谓词集类似于20个不同的谓词,因此以某种方式列出它们是可以管理的,但如果它是以组合方式列出则不行。

1 个答案:

答案 0 :(得分:0)

特别针对正则表达式:如果你的目标只是让它更容易阅读,你可以按照这些方式做点什么:

FILTER(STRSTARTS(STR(?p), STR(rdf:)) || STRSTARTS(STR(?p), STR(shacl:))) 

这样可以节省必须使用带有完整命名空间IRI的长正则表达式,而且还可以将逻辑OR从正则表达式移出到SPARQL过滤器逻辑本身(这可能更有效)。

除此之外,我没有立即在单个SPARQL查询中看到一种简单的方法来改进这一点。但是,如果您愿意妥协并对结果进行一些后期处理,那么您可以通过更简单的查询得到相当接近。

通常情况下,使用简单的DESCRIBE查询可以很好地处理这种事情:

DESCRIBE ex:toExport

但是,您的方案中有两个要求会使这更加困难:

    还应返回
  1. :pred-7的值:DESCRIBE通常只返回所描述资源的空白节点闭包,因此这不是一个完整的答案。
  2. 只返回某些属性:DESCRIBE通常会返回所有属性。
  3. 对于第一个问题,我们可以扩展DESCRIBE查询以更接近您的预期结果。例如,我们可以修改它,不仅可以描述ex:toExport,还可以通过其中一个想要的属性描述与?x连接的IRI的所有资源ex:toExport

    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的属性。

    过滤掉那些不需要的属性当然可以在后期处理中完成,但这是否适合您的场景取决于“不需要的”的数量。首先是数据中的属性。

    最后一点需要注意:DESCRIBE查询的确切结果取决于实现。 大多数实现返回某种形式的空白节点闭包,但有一些变体。检查SPARQL引擎的文档(或者给它一个测试旋转以查看它的作用)。