将SPARQL查询结果限制为层次结构中的第一级

osy*_*yan 4 c# sparql

我正在使用C#对我的N3数据文件执行查询.如何将结果限制为节点的第一级子节点.例如:

project
      |
      |__ main
      |      |__m1
      |      |__m2
      |   
      |__ SUB
          |__A
          |  |__A1
          |  |__A2
          | 
          |__B
          |__C
          |  |__C1
          |  
          |__D
Run Code Online (Sandbox Code Playgroud)

一个示例查询,它导致SUB的所有节点级别:

 select ?object where { 
 :SUB rdfs:superClassOf* ?object
 }
Run Code Online (Sandbox Code Playgroud)

结果将是:

          |__A
          |  |__A1
          |  |__A2
          | 
          |__B
          |__C
          |  |__C1
          |  
          |__D
Run Code Online (Sandbox Code Playgroud)

但是我想把结果限制在这样的第一级孩子:

          |__A
          |__B
          |__C
          |__D
Run Code Online (Sandbox Code Playgroud)

Jos*_*lor 6

选择长度为1的路径

使用的属性路径*查找长度为zeor或更大的路径.如果您想要长度恰好为1的路径,只需删除*:

 select ?object where { 
   :SUB rdfs:superClassOf ?object
 }
Run Code Online (Sandbox Code Playgroud)

我注意到RDFS只定义了rdfs:subClassOf,而不是rdfs:superClassOf你在查询中使用过的.不过,我会认为这只是问题的一个错字.我认为你想要的实际查询是:

select ?subclass where { 
  ?subclass rdfs:subClassOf :SUB
}
Run Code Online (Sandbox Code Playgroud)

选择任意长度的路径

本节中的解决方案基于对在RDF列表中查找元素位置的问题的答案.考虑这些数据:

@prefix : <urn:ex:> .

:a :p :b, :c .
:b :p :d, :e .
Run Code Online (Sandbox Code Playgroud)

此查询查找链p以及链的长度:

prefix : <urn:ex:>

select ?sub ?sup (count(?mid)-1 as ?distance) where { 
  ?sub :p* ?mid .
  ?mid :p* ?sup .
}
group by ?sub ?sup
order by ?sub ?sup

$ arq --data data.n3 --query query.sparql
------------------------
| sub | sup | distance |
========================
| :a  | :a  | 0        |
| :a  | :b  | 1        |
| :a  | :c  | 1        |
| :a  | :d  | 2        |
| :a  | :e  | 2        |
| :b  | :b  | 0        |
| :b  | :d  | 1        |
| :b  | :e  | 1        |
| :c  | :c  | 0        |
| :d  | :d  | 0        |
| :e  | :e  | 0        |
------------------------
Run Code Online (Sandbox Code Playgroud)

因为我们可以在那个长度上获得路径的filter长度,并获得我们想要的路径.例如:

prefix : <urn:ex:>

select ?sub ?sup where { 
  { 
    select ?sub ?sup (count(?mid)-1 as ?distance) where { 
      ?sub :p* ?mid .
      ?mid :p* ?sup .
    }
    group by ?sub ?sup
    order by ?sub ?sup
  }
  filter( ?distance = 2 )
  # filter ( ?distance > 2 )   # alternative
  # filter ( ?distance < 10 )  # alternative
}

$ arq --data data.n3 --query query.sparql
-------------
| sub | sup |
=============
| :a  | :d  |
| :a  | :e  |
-------------
Run Code Online (Sandbox Code Playgroud)

如果只需要较小但特定长度的路径,则可以手动展开属性路径.例如,对于长度为2的路径:

prefix : <urn:ex:>

select ?sub ?sup {
  ?sub :p/:p ?sup .
}
Run Code Online (Sandbox Code Playgroud)

对于一系列数字,例如1-2,您可以使用?匹配零或一的数字:

prefix : <urn:ex:>

select ?sub ?sup {
  ?sub :p/:p? ?sup .
}
Run Code Online (Sandbox Code Playgroud)

有关属性路径的更多信息,请务必查看SPARQL 1.1规范中的第9节" 属性路径 ".

  • @osyan您不应该在RDFS命名空间中定义属性.许多工具会将命名空间视为保留,如果您使用未由标准定义的IRI,则会抱怨.做一个是微不足道的,做任何数字(用`*`)很容易,但做一个特定的数字有点复杂.我会用一个例子来更新答案. (2认同)
  • @osyan,定义自己的关系没有错.Joshua的观点是你不应该使用rdfs命名空间创建自己的关系.所以创建`rdfs:superClassOf`是错误的,但创建`my:superClassOf`就好了(假设前缀`my`映射到你的contro下的某个命名空间). (2认同)