启用正向链接后,我将执行以下操作:
"...WHERE { ?class rdf:type rdfs:Class }"
现在,我想不用推理机来做,所以我尝试了:
"...WHERE { ?class rdf:type* rdfs:Class }"
但这给了我类的实例,而不是所有的类。例如,缺少
rdfs:Resource
。有任何想法吗?如果重要的话,我的本体是here。 最佳答案
如果没有理由,您将无法获得100%保证的完整结果。例如,rdfs:Resource
经常根本没有在数据集中被显式使用,因此无需推断该类根本就不会出现在数据中。但是对于大多数实际目的,您可以足够接近完整性。
什么时候知道某类资源?有多种可能性:
当它是rdfs:Class
类型时;
当它是rdf:type
关系的对象时;
当它是rdfs:subClassOf
关系的主题或对象时;
当用作rdfs:domain
或rdfs:range
关系的对象时。
那么,如何查询呢?好吧,第一个很简单:
SELECT ?c WHERE { ?c a rdfs:Class }
顺便说一句:在SPARQL中,关键字
a
是rdf:type
关系的简写。请注意,您不需要传递查询(因此不需要*
)。第二个也很简单:
SELECT ?c WHERE { [] rdf:type ?c }
[]
位表示一个匿名变量(因为我们对主题值不感兴趣-此时我们只需要对象)。第三个有点棘手。我们可以将其分为两部分:首先查询所有属于
rdfs:subClassOf
关系的资源:SELECT ?c WHERE { ?c rdfs:subClassOf [] }
然后查询作为关系对象的所有资源:
SELECT ?c WHERE { [] rdfs:subClassOf ?c }
现在,让我们看看是否可以在单个查询中结合这两种模式。我们不能像这样将两个图形模式放在同一个WHERE子句中,因为那样会使它成为逻辑AND(这意味着我们只会取回属于子类关系的主题和对象的资源)。因此,我们需要使用逻辑或。在SPARQL中,可以使用
UNION
来完成:SELECT ?c
WHERE {
{ ?c rdfs:subClassOf [] }
UNION
{ [] rdfs:subClassOf ?c }
}
但是,在这种情况下,我们还可以使用属性路径表达式以不同的方式表示逻辑或,如下所示:
SELECT ?c
WHERE { ?c rdfs:subClassOf|^rdfs:subClassOf [] }
路径表达式
p1|p2
表示“与这两个关系中的任何一个匹配”。运算符^
说“查询关系的倒数”。因此,如果我们将它们放在一起,则上面的路径表达式会说“匹配任何三元组,其中主语是?c
且关系是rdfs:subClassOf
,或者关系rdfs:subClassOf
是倒置的,因此对象与?c
”。我们可以用类似的方式查询第四个可能性:
SELECT ?c
WHERE { [] rdfs:domain|rdfs:range ?c }
放在一起
SELECT ?c
WHERE {
{ ?c a rdfs:Class }
UNION
{ [] rdf:type ?c }
UNION
{ [] rdfs:domain|rdfs:range ?c }
UNION
{ ?c rdfs:subClassOf|^rdfs:subClassOf [] }
}
这可能可以进一步缩短。当然,如果您很了解本体,就可以进一步简化它(例如,如果您知道自己从不使用域或范围属性,则可以省略该位)。