首页 > 解决方案 > 基于 CONSTRUCT 子查询中定义的新属性的 SPARQL 属性路径

问题描述

给定以下模式,可以很容易地看到“司机-乘客”血统:

tp:trip a owl:Class ;
    rdfs:label "trip"@en ;
    rdfs:comment "an 'asymmetric encounter' where someone is driving another person."@en .

tp:driver a owl:ObjectProperty ;
    rdfs:label "driver"@en ;
    rdfs:comment "has keys."@en ;
    rdfs:domain tp:trip ;
    rdfs:range tp:person .

tp:passenger a owl:ObjectProperty ;
    rdfs:label "passenger"@en ;
    rdfs:comment "has drinks."@en ;
    rdfs:domain tp:trip ;
    rdfs:range tp:person .

考虑以下数据:

<alice> a tp:person .
<grace> a tp:person .
<tim> a tp:person .
<ruth> a tp:person .

<trip1> a tp:trip ;
    tp:participants   <alice> , <grace> ;
    tp:driver         <alice> ;
    tp:passenger         <grace> .

<trip2> a tp:trip ;
    tp:participants   <alice> , <tim> ;
    tp:driver         <alice> ;
    tp:passenger         <tim> .

<trip3> a tp:trip ;
    tp:participants   <tim> , <grace> ;
    tp:driver         <tim> ;
    tp:passenger         <grace> .

<trip4> a tp:trip ;
    tp:participants   <grace> , <ruth> ;
    tp:driver         <grace> ;
    tp:passenger         <ruth> .

<trip5> a tp:trip ;
    tp:participants   <grace> , <tim> ;
    tp:driver         <grace> ;
    tp:passenger         <tim> .

现在让“司机-乘客后代”成为tp:passenger行程序列末尾的任意一个行程tp:passenger,其中一次行程的 是tp:driver下一次行程的

前任。<ruth><alice>根据以下行程序列的后代:

<trip2>-> <trip3>-> <trip4>

问题: 如何获得所有驾驶员 - 乘客血统的(祖先,后代)对?

尝试 1: 我最初尝试了以下 CONSTRUCT 子查询来定义对象属性:tp:drove,可以在属性路径中轻松使用。但是,这不适用于我的实际数据:

SELECT ?originalDriver ?passengerDescendent
WHERE {
    ?originalDriver tp:drove+ ?passengerDescendent .
    {
        CONSTRUCT { ?d tp:drove ?p . }
        WHERE { ?t a tp:trip .
                ?t tp:driver ?d . 
                ?t tp:passenger ?p .}        
    }
}

尝试 2: 我尝试创建将祖先表示为乘客驱动程序的属性路径,但我认为我没有正确理解它应该如何工作:

(tp:driver/^tp:passenger)+

关于 MWE:是否有某种 RDF 沙箱允许我通过定义像tp上面这样的简单本体以及一些示例数据来创建 MWE?以下“游乐场”可用,但似乎都不支持定义玩具本体:SPARQL PlaygroundSPARQL Explorer


相关内容注释:

这个问题与上一个问题直接相关,但不再需要自己保存路径,这是 SPARQL 1.1 不直接支持的功能。

Joshua Taylor 的这个答案似乎是相关的,但没有解决特定类型路径的识别,例如上面定义的谱系。

标签: sparqlrdf

解决方案


这个似乎可以解决问题:

select ?driver ?passenger where {
?driver (^tp:driver/tp:passenger)+ ?passenger .
filter( ?driver != ?passenger)
}

如果您还想查看指向同一个人的关系,则可以删除过滤条件。


推荐阅读