【问题标题】:How can retrieve relation between 2 class with object property using sparql query如何使用 sparql 查询检索 2 个类与对象属性之间的关系
【发布时间】:2015-04-20 00:29:01
【问题描述】:

假设我们有一个 OWL 文件,其中包含以下属性以及域和范围:

Domain   Property    Range
----------------------------
tour     hascountry  country
country  hascity     city
city     hasward     ward
ward     hashouse    house

使用 SPARQL,我如何在 Tour 和 House 类之间获得结果?也就是说,其域和范围的属性存在从 Tour 到域以及从范围到 House 的“路径”。只有这两个类,我们怎么能找到像下面这样的结果呢?似乎某种循环可能是必要的,但我不知道如何在 SPARQL 中执行此操作。

|tour    -------- (hascountry) ----- country|
|country -------- (hascity)    ----- city   |
|city    -------- (hasward)    ----- ward   |
|ward    -------- (hashouse)   ----- house  |

【问题讨论】:

    标签: sparql owl protege


    【解决方案1】:

    首先,处理一些真实数据总是更容易。我们无法针对我们没有的数据编写真正的 SPARQL 查询。将来,请务必提供一些我们可以使用的样品。现在,这里有一些示例数据,描述了您提到的属性的域和范围。另请注意,属性不连接类;属性连接个人。属性可以具有域和范围,这为我们提供了一种推断与属性相关的个人的附加信息的方法。无论如何,这是数据:

    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix : <https://stackoverflow.com/q/29737549/1281433/> .
    
    :hascountry rdfs:domain :tour    ; rdfs:range :country .
    :hascity    rdfs:domain :country ; rdfs:range :city .
    :hasward    rdfs:domain :city    ; rdfs:range :ward .
    :hashouse   rdfs:domain :ward    ; rdfs:range :house .
    

    现在,请注意,如果您按照 rdfs:domain 属性向后 到 :hascountry,然后按照 rdfs:range 属性向前,您可以从 :tour 到 :country em> 到:国家。在 SPARQL 中,您可以将其写为属性路径:

    :tour ^rdfs:domain/rdfs:range :country
    

    如果您可以跟踪该属性路径的,则可以找到“介于” :tour 和 :house: 之间的所有属性:

    prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    prefix : <https://stackoverflow.com/q/29737549/1281433/>
    
    select ?domain ?property ?range  where {
      #-- find ?properties that have a domain
      #-- and range...
      ?property rdfs:domain ?domain ;
                rdfs:range ?range .
    
      #-- where there's a ^rdfs:domain to rdfs:range
      #-- chain from :tour to ?domain...
      :tour (^rdfs:domain/rdfs:range)* ?domain .
    
      #-- and from ?range to :house.
      ?range (^rdfs:domain/rdfs:range)* :house .
    }
    

    -------------------------------------
    | domain   | property    | range    |
    =====================================
    | :ward    | :hashouse   | :house   |
    | :city    | :hasward    | :ward    |
    | :country | :hascity    | :city    |
    | :tour    | :hascountry | :country |
    -------------------------------------
    

    “按顺序”获取结果

    如果您希望属性“按顺序”从开始类到结束类,您可以计算从开始类到每个属性的距离并按此排序。您可以使用my answerIs it possible to get the position of an element in an RDF Collection in SPARQL? 中的技术来做到这一点。这是 SPARQL 查询的样子:

    prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    prefix : <https://stackoverflow.com/q/29737549/1281433/>
    
    select ?domain ?property ?range
           (count(?mid) as ?dist)
    where {
      #-- find ?properties that have a domain
      #-- and range...
      ?property rdfs:domain ?domain ;
                rdfs:range ?range .
    
      #-- where there's a ^rdfs:domain to rdfs:range
      #-- chain from :tour to ?domain...
      :tour (^rdfs:domain/rdfs:range)* ?domain .
    
      #-- and from ?range to :house.
      ?range (^rdfs:domain/rdfs:range)* :house .
    
      #-- then, compute the "distance" from :tour
      #-- to the property.  This is based on binding
      #-- ?mid to each class in between them and
      #-- taking the number of distinct ?mid values
      #-- as the distance.
      :tour (^rdfs:domain/rdfs:range)* ?mid .
      ?mid (^rdfs:domain/rdfs:range)* ?domain .
    }
    group by ?domain ?property ?range
    order by ?dist
    

    --------------------------------------------
    | domain   | property    | range    | dist |
    ============================================
    | :tour    | :hascountry | :country | 1    |
    | :country | :hascity    | :city    | 2    |
    | :city    | :hasward    | :ward    | 3    |
    | :ward    | :hashouse   | :house   | 4    |
    --------------------------------------------
    

    我在选择中包含了 ?dist 以便我们可以看到这些值。您不必选择它就可以按它排序。你也可以这样做:

    select ?domain ?property ?range {
      #-- ...
    }
    group by ?domain ?property ?range 
    order by count(?mid)
    

    -------------------------------------
    | domain   | property    | range    |
    =====================================
    | :tour    | :hascountry | :country |
    | :country | :hascity    | :city    |
    | :city    | :hasward    | :ward    |
    | :ward    | :hashouse   | :house   |
    -------------------------------------
    

    【讨论】:

    • 太多了。很详细。这就是我需要的:)。我们可以像类关系那样按顺序得到结果吗? (旅游->国家-->城市-->病房)。我运行上面的查询语句,我得到结果:ward--> city-->tour-->country
    • @VanLanhLuu 是的,你可以做到。它有点复杂,但不是很多。我已经更新了我的答案。
    • 干得好。我实际上是想让一个人在一定程度上分开,比如说前。 :danbry foaf:knows/foaf:knows/foaf:name ?name 有 2 个分离度。
    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多