Sparql查询集合和rdf:容器?

Max*_*Max 7 containers rdf sparql

嗨所有rdf/sparql开发人员.这个问题一直困扰着我一段时间,但似乎没有人能够准确地回答它,因为rdf和sparql规范已经发布.

为了说明这种情况,RDF定义了几种处理资源多值属性的方法; 从使用相同的subjet-predicate uris创建尽可能多的三元组到集合或容器.这一切都很好,因为每个模式都有自己的特点.

但是从SPARQL的观点来看,在我看来,查询这些结构导致过于复杂的查询(更糟糕的是)无法转录为合理的结果集:您不能使用变量来查询任意长度,而propertyPath也是如此不保留"自然"秩序.

在一种天真的方式中,在许多SELECT或ASK查询中,如果我想查询或过滤容器或列表的值,我绝大多数时候都不会关心底层模式究竟是什么(如果有的话).例如:

<rdf:Description rdf:about="urn:1">
    <rdfs:label>
        <rdf:Alt>
            <rdf:li xml:lang="fr">Exemple n°1</rdf:li>
            <rdf:li xml:lang="en">Example #1</rdf:li>
        </rdf:Alt>
    </rdfs:label>
    <my:release>
        <rdf:Seq>
            <rdf:li>10.0</rdf:li>
            <rdf:li>2.4</rdf:li>
            <rdf:li>1.1.2</rdf:li>
            <rdf:li>0.9</rdf:li>
        </rdf:Seq>
    </my:release>
</rdf:Description>

<rdf:Description rdf:about="urn:2">
    <rdfs:label xml:lang="en">Example #2</rdfs:label>
</rdf:Description>
Run Code Online (Sandbox Code Playgroud)

显然我希望两种资源都能回答这个问题:

SELECT ?res WHERE { ?res rdfs:label ?label . FILTER ( contains(?label, 'Example'@en) }
Run Code Online (Sandbox Code Playgroud)

我也希望查询:

SELECT ?ver WHERE { <urn:1> my:release ?ver }
Run Code Online (Sandbox Code Playgroud)

按原始顺序返回rdf:Seq元素(或任何rdf:Alt)(对于其他模式,如果保留原始顺序无关紧要,为什么不保留它呢?) - 除非明确指定通过ORDER BY子句.

当然,有必要保持与旧方法的兼容性,所以也许有可能使用new运算符扩展propertyPath语法?

我觉得它会简化日常的SPARQL用例.

这对你有意义吗?此外,你有没有理由不尝试实施这个?

编辑更正了示例的urn:2 rdfs:标签值不正确

use*_*838 5

RDF 定义了集合和容器的词汇表,但它们在如何解释包含它们的图形方面没有特殊意义。它们不是用于表示多值属性的,也不适合用于表示多值属性。

一般来说,说:

:A :predicate [ a rdf:Alt ; rdf:_1 :B ; rdf:_2 :C ] .
Run Code Online (Sandbox Code Playgroud)

不等于

:A :predicate :B , :C .
Run Code Online (Sandbox Code Playgroud)

假设谓词是 owl:sameAs:

:A owl:sameAs [ a rdf:Alt ; rdf:_1 :B ; rdf:_2 :C ] .
Run Code Online (Sandbox Code Playgroud)

上面说 :A 命名一个包含:B 和 :C的个体,而:

:A owl:sameAs :B , :C .
Run Code Online (Sandbox Code Playgroud)

说:A、:B 和:C 是同一个人。

SPARQL 与容器和集合无关(除了 rdf:List 的语法简写)。如果您想要更方便的处理集合的方式,包括Jenardflib在内的许多 RDF API都为它们提供了一流的表示。

附录

对多值属性建模的方法——即,对“Example n°1”@fr 和“Example #1”@en 都是 urn:1 的标签进行建模——是简单地陈述两个事实:

<rdf:Description rdf:about="urn:1">
    <rdfs:label xml:lang="fr">Exemple n°1</rdfs:label>
    <rdfs:label xml:lang="en">Example #1</rdfs:label>
    ...
</rdf:Description>
Run Code Online (Sandbox Code Playgroud)

和查询:

SELECT ?res WHERE { ?res rdfs:label ?label . FILTER ( contains(?label, 'Example'@en) ) }
Run Code Online (Sandbox Code Playgroud)

将匹配 <urn:1> 和 <urn:2> 的英文标签。

对于 my:release 属性,您有一个多值属性并对其值进行排序,这有点棘手。您可以定义一个新属性(例如)my:releases,其值为 rdf:List 或 rdf:Seq。my:release 给出了直接关系,而 my:releases 给出了一个间接关系,指定了一个明确的顺序。使用推理存储和适当的规则,您只需提供后者。不幸的是,这并没有使在 SPARQL 中使用排序变得更容易。

在 SPARQL 和非推理存储中更容易使用的方法是使版本本身成为具有定义排序属性的对象:

  <rdf:Description rdf:about="urn:1">
    <rdfs:label xml:lang="fr">Exemple n&#xB0;1</rdfs:label>
    <rdfs:label xml:lang="en">Example #1</rdfs:label>
    <my:release>
      <my:Release>
        <dc:issued rdf:datatype="&xsd;date">2008-10-10/dc:issued>
        <my:version>10.0</my:version>
      </my:Release>
    </my:release>
    <my:release>
      <my:Release>
        <my:version>2.4</my:version>
        <dc:issued rdf:datatype="&xsd;date">2007-05-01</dc:issued>
      </my:Release>
    </my:release>
    ...
  </rdf:Description>
Run Code Online (Sandbox Code Playgroud)

在上面,日期可用于对结果进行排序,因为不再有明确的顺序。查询只是稍微复杂一点:

SELECT ?ver 
WHERE { <urn:1> my:release [ my:version ?ver ; dc:issued ?date ] }
ORDER BY ?date
Run Code Online (Sandbox Code Playgroud)


Jos*_*lor 5

我意识到这个问题已经有了答案,但是值得一看的是,如果使用RDF列表而不是其他类型的RDF容器,可以在这里做什么。首先,您在Turtle中提供的数据(在提供名称空间声明之后)是:

@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix my:    </sf/ask/1135616681/> .

<urn:2>  rdfs:label  "Example #2"@en .

<urn:1>  rdfs:label  [ a       rdf:Alt ;
                       rdf:_1  "Exemple n°1"@fr ;
                       rdf:_2  "Example #1"@en
                     ] ;
        my:release  [ a       rdf:Seq ;
                      rdf:_1  "10.0" ;
                      rdf:_2  "2.4" ;
                      rdf:_3  "1.1.2" ;
                      rdf:_4  "0.9"
                    ] .
Run Code Online (Sandbox Code Playgroud)

属性rdf:_n是这里的难点,因为它们是唯一为序列中的元素提供任何真实顺序的东西。(虽然alt仍然使用rdf:_n属性,但alt实际上并没有重要的顺序。)如果使用使rdf:_n属性可选的SPARQL属性路径,则可以获取所有三个标签:

prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?x ?label where {
  ?x rdfs:label/(rdf:_1|rdf:_2|rdf:_3)* ?label
  filter( isLiteral( ?label ))
}
Run Code Online (Sandbox Code Playgroud)
------------------------------
| x       | label            |
==============================
| <urn:1> | "Exemple n°1"@fr |
| <urn:1> | "Example #1"@en  |
| <urn:2> | "Example #2"@en  |
------------------------------
Run Code Online (Sandbox Code Playgroud)

让我们看看可以使用RDF列表做什么。如果使用列表,则数据是这样的:

@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix my:    </sf/ask/1135616681/> .

<urn:2>  rdfs:label  "Example #2"@en .

<urn:1>  rdfs:label  ( "Exemple n°1"@fr "Example #1"@en ) ;
        my:release  ( "10.0" "2.4" "1.1.2" "0.9" ) .
Run Code Online (Sandbox Code Playgroud)

现在,您可以相对轻松地获得标签:

prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?x ?label where {
  ?x rdfs:label/(rdf:rest*/rdf:first)* ?label
  filter( isLiteral( ?label ))
}
Run Code Online (Sandbox Code Playgroud)
------------------------------
| x       | label            |
==============================
| <urn:1> | "Exemple n°1"@fr |
| <urn:1> | "Example #1"@en  |
| <urn:2> | "Example #2"@en  |
------------------------------
Run Code Online (Sandbox Code Playgroud)

如果您希望标签在标签列表中的位置,您甚至可以得到它,尽管这会使查询更加复杂:

prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?x ?label (count(?mid)-1 as ?position) where {
  ?x rdfs:label ?y .
  ?y rdf:rest* ?mid . ?mid rdf:rest*/rdf:first? ?label .
  filter(isLiteral(?label))
}
group by ?x ?label
Run Code Online (Sandbox Code Playgroud)
-----------------------------------------
| x       | label            | position |
=========================================
| <urn:1> | "Exemple n°1"@fr | 0        |
| <urn:1> | "Example #1"@en  | 1        |
| <urn:2> | "Example #2"@en  | 0        |
-----------------------------------------
Run Code Online (Sandbox Code Playgroud)

这使用了SPARQL中的RDF集合中的元素位置是否可以得到?计算列表中每个值的位置,这些值是的对象rdfs:label,从开始0,并分配0给不在列表中的元素。