当我启用了正向链接时,我会这样做:
=MATCH(MID(B1,FIND("@",B1),LEN(B1)),A:A,0)
现在,我想在没有推理器的情况下这样做,所以我尝试了:
"...WHERE { ?class rdf:type rdfs:Class }"
但这给了我类的实例而不是所有的类。例如,"...WHERE { ?class rdf:type* rdfs:Class }"
缺失。有任何想法吗?如果重要的话,我的本体论是here。
答案 0 :(得分:3)
如果没有任何推理,您将无法获得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(意味着我们只会获取那些既是主题又对象的资源一个子类关系)。所以我们需要使用逻辑OR。在SPARQL中,可以使用UNION
:
SELECT ?c
WHERE {
{ ?c rdfs:subClassOf [] }
UNION
{ [] rdfs:subClassOf ?c }
}
但是,在这种情况下,我们也可以使用属性路径表达式以不同的方式表达逻辑OR,如下所示:
SELECT ?c
WHERE { ?c rdfs:subClassOf|^rdfs:subClassOf [] }
路径表达式p1|p2
表示“与这两种关系中的任何一种匹配”。运算符^
表示“查询关系的倒数”。因此,如果我们把它放在一起,上面的路径表达式“匹配任何三元组,其中主题是?c
,关系是rdfs:subClassOf
,或者关系rdfs:subClassOf
被反转,因此 object 与?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 [] }
}
这可能会进一步缩短。当然,如果你很了解你的本体,你可以进一步简化它(例如,如果你知道你从不使用域或范围属性,你可以忽略这一点)。