Sparql 1.1获取特定类的所有实例,但不包括子类的任何实例

Sparql 1.1获取特定类的所有实例,但不包括子类的任何实例,sparql,owl,Sparql,Owl,我正在基于RDFS/OWL创建一个类层次结构,并使用a(rdf:type)关系在所有类中创建实例。我想检索特定类的实例,不包括其子类的实例。但是,当我编写SPARQL查询时,它也会给出每个子类的所有实例 我的本体说: Book是一个类,它有两个子类:hard\u-bounded\u-Book和soft\u-binding\u-books 换句话说(在某些情况下): @前缀ex:。 @前缀rdf:。 @前缀rdfs:。 例:硬装订书籍1 一本硬装订的书。 例:软装订书籍1A 例:软装订的书。 例如

我正在基于RDFS/OWL创建一个类层次结构,并使用
a
rdf:type
)关系在所有类中创建实例。我想检索特定类的实例,不包括其子类的实例。但是,当我编写SPARQL查询时,它也会给出每个子类的所有实例

我的本体说:

Book
是一个类,它有两个子类:
hard\u-bounded\u-Book
soft\u-binding\u-books

换句话说(在某些情况下):

@前缀ex:。
@前缀rdf:。
@前缀rdfs:。
例:硬装订书籍1
一本硬装订的书。
例:软装订书籍1A
例:软装订的书。
例如:软装订书籍rdfs:例如:书籍的子类。
ex:hard_bounded_book rdfs:ex:book的子类。
例如:预订一个rdf:Class。
例如:书。
当我询问

PREFIX  rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX  ex:  <http://book_triples.org/>
SELECT  ?book
WHERE
  { ?book  rdf:type  ex:Book }
前缀rdf:
前缀ex:
选择书
哪里
{?book rdf:type ex:book}
它返回所有三个
Book1
hard\u-bounded\u-Book1
soft\u-bounded\u-Book1
,但我只想得到第一个结果(
Book1


感谢您的帮助。谢谢。

我编辑了您的问题,以提供格式良好的输入和查询。我有没有歪曲什么

我真的怀疑这是一个推理或推理问题。您使用的是什么triplestore?您知道是否启用了推理功能吗

当我将您的三元组插入Blazegraph,并关闭
推断
并运行您的查询时,我得到了所需的结果:

+----------------------------------------------+
|                     book                     |
+----------------------------------------------+
| <http://book_triples.org/Book1>              |
+----------------------------------------------+
+----------------------------------------------+
|书|
+----------------------------------------------+
|               |
+----------------------------------------------+
当我打开推理时,我得到了您描述的结果:

+----------------------------------------------+
|                     book                     |
+----------------------------------------------+
| <http://book_triples.org/Book1>              |
| <http://book_triples.org/hard_bounded_book1> |
| <http://book_triples.org/soft_binded_books1> |
+----------------------------------------------+
+----------------------------------------------+
|书|
+----------------------------------------------+
|               |
|  |
|  |
+----------------------------------------------+

无论推断在存储中是打开还是关闭,您都可以编写只返回特定类实例的查询,方法如下: 过滤掉所有也是
ex:Book
子类实例的实例,如下所示:

SELECT  ?book
WHERE { 
  ?book  rdf:type  ex:Book 
  FILTER NOT EXISTS { 
     ?book rdf:type ?c . 
     ?c rdfs:subClassOf+ ex:Book .
     FILTER (?c != ex:Book)  
}
它检查每返回一本书,使该书成为
ex:book
子类实例的三元组不存在。第二个过滤器(检查
?c
是否不等于
ex:Book
)是必需的,因为在RDFS中,每个类都是自己的子类

当然,这个查询的运行成本要比原来的简单查询高,因此如果您的triplestore可以选择(暂时)关闭推断,那么这可能是一个更好的解决方案

顺便说一句:
模式的
子类后面的
+
符号是一个“1或更多级别的深度”操作符,在这里是可选的。如果您希望严格排除子类的所有可能实例,即使推理者已经完成了所有推断,也需要包含它。考虑到在你的场景中,很可能有一个推理器可以推断出完整的演绎闭包,你可以省略它

更新更详细地解释我关于
+
符号的观点:假设我们有a、B和C类:B是a的子类,C是B的子类

想象一个单独的x,它被声明为C的一个实例

  • 在没有推断的情况下,对A的所有实例的任何查询都不会返回x,无论我们是否过滤掉查询中的子类
  • 通过推断,x将被推断为类型B和类型A,因此不带
    +
    符号的子类筛选器将从 结果 到目前为止还不错。但是,假设我们还插入了一个明确的事实,即x是A的一个实例


    如果启用了推断,我们仍然可以使用没有
    +
    运算符的查询。但是,在不进行推断的情况下,对A的所有实例的查询现在将返回x,即使x也是A(即C)的(间接)子类的实例。这就是边缘情况,
    +
    操作符非常有用。

    您使用哪种API或triple store?谢谢。这就解决了问题。2个问题:有没有办法在询问时暂时停止推断。如果我不使用+号,它会忽略直接子类,从而忽略所有后续子类。是否真的需要+符号?问题1:这取决于您使用的是哪个三元组。问题2:我将编辑答案,快速勾勒出为什么有必要。明白了。再次感谢。
    SELECT  ?book
    WHERE { 
      ?book  rdf:type  ex:Book 
      FILTER NOT EXISTS { 
         ?book rdf:type ?c . 
         ?c rdfs:subClassOf+ ex:Book .
         FILTER (?c != ex:Book)  
    }