查找所有类,无需推理
Find all classes, without reasoning
当我启用前向链接时,我会做:
"...WHERE { ?class rdf:type rdfs:Class }"
现在,我想在没有推理机的情况下进行,所以我尝试了:
"...WHERE { ?class rdf:type* rdfs:Class }"
但这给了我 类 而不是所有 类 的实例。例如缺少 rdfs:Resource
。有任何想法吗?我的 ontology,如果重要的话,是 here。
如果没有推理,您将无法获得 100% 保证的完整结果。例如,rdfs:Resource
通常根本不会在数据集中明确使用,因此无需推理 class 根本不会出现在您的数据中。但是对于大多数实际用途,您可以接近完整性。
什么时候已知某些资源是 class?有多种可能性:
- 当它是
rdfs:Class
类型时;
- 当它是
rdf:type
关系的对象时;
- 当它是
rdfs:subClassOf
关系的主语或宾语时;
- 当它用作
rdfs:domain
或rdfs:range
关系的对象时。
那么,这个怎么查询呢?那么第一个很简单:
SELECT ?c WHERE { ?c a rdfs:Class }
顺便说一句:在 SPARQL 中,关键字 a
是 rdf:type
关系的 shorthand。请注意,您不需要传递地查询它(因此不需要 *
)。
第二个也很简单:
SELECT ?c WHERE { [] rdf:type ?c }
[]
位表示一个匿名变量(因为我们对主题值不感兴趣 - 此时我们只想要对象)。
第三个有点棘手。我们可以将其分为两部分:首先查询属于 rdfs:subClassOf
关系的 subject 的所有资源:
SELECT ?c WHERE { ?c rdfs:subClassOf [] }
然后查询关系的对象的所有资源:
SELECT ?c WHERE { [] rdfs:subClassOf ?c }
现在,让我们看看是否可以将这两种模式组合在一个查询中。我们不能像那样将两个图形模式放在同一个 WHERE 子句中,因为那样会使它成为一个逻辑 AND(这意味着我们只会取回那些都属于 and[=78 主题的资源=] subclass 关系的对象)。所以我们需要使用逻辑或。在 SPARQL 中,这可以通过 UNION
:
SELECT ?c
WHERE {
{ ?c rdfs:subClassOf [] }
UNION
{ [] rdfs:subClassOf ?c }
}
然而,在这种情况下,我们还可以使用 属性 路径表达式以不同的方式表达逻辑或,如下所示:
SELECT ?c
WHERE { ?c rdfs:subClassOf|^rdfs:subClassOf [] }
路径表达式p1|p2
表示"match with any of these two relations"。运算符 ^
表示 "query the inverse of the relation"。所以如果我们把它们放在一起,上面的路径表达式就是 "match with any triples where the subject is ?c
and the relation is rdfs:subClassOf
, or where the relation rdfs:subClassOf
is inverted and thus the object matches with ?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 [] }
}
这可能会进一步缩短。当然,如果您对 ontology 非常了解,则可以进一步简化它(例如,如果您知道自己从不使用域或范围属性,则可以省略该位)。
当我启用前向链接时,我会做:
"...WHERE { ?class rdf:type rdfs:Class }"
现在,我想在没有推理机的情况下进行,所以我尝试了:
"...WHERE { ?class rdf:type* rdfs:Class }"
但这给了我 类 而不是所有 类 的实例。例如缺少 rdfs:Resource
。有任何想法吗?我的 ontology,如果重要的话,是 here。
如果没有推理,您将无法获得 100% 保证的完整结果。例如,rdfs:Resource
通常根本不会在数据集中明确使用,因此无需推理 class 根本不会出现在您的数据中。但是对于大多数实际用途,您可以接近完整性。
什么时候已知某些资源是 class?有多种可能性:
- 当它是
rdfs:Class
类型时; - 当它是
rdf:type
关系的对象时; - 当它是
rdfs:subClassOf
关系的主语或宾语时; - 当它用作
rdfs:domain
或rdfs:range
关系的对象时。
那么,这个怎么查询呢?那么第一个很简单:
SELECT ?c WHERE { ?c a rdfs:Class }
顺便说一句:在 SPARQL 中,关键字 a
是 rdf:type
关系的 shorthand。请注意,您不需要传递地查询它(因此不需要 *
)。
第二个也很简单:
SELECT ?c WHERE { [] rdf:type ?c }
[]
位表示一个匿名变量(因为我们对主题值不感兴趣 - 此时我们只想要对象)。
第三个有点棘手。我们可以将其分为两部分:首先查询属于 rdfs:subClassOf
关系的 subject 的所有资源:
SELECT ?c WHERE { ?c rdfs:subClassOf [] }
然后查询关系的对象的所有资源:
SELECT ?c WHERE { [] rdfs:subClassOf ?c }
现在,让我们看看是否可以将这两种模式组合在一个查询中。我们不能像那样将两个图形模式放在同一个 WHERE 子句中,因为那样会使它成为一个逻辑 AND(这意味着我们只会取回那些都属于 and[=78 主题的资源=] subclass 关系的对象)。所以我们需要使用逻辑或。在 SPARQL 中,这可以通过 UNION
:
SELECT ?c
WHERE {
{ ?c rdfs:subClassOf [] }
UNION
{ [] rdfs:subClassOf ?c }
}
然而,在这种情况下,我们还可以使用 属性 路径表达式以不同的方式表达逻辑或,如下所示:
SELECT ?c
WHERE { ?c rdfs:subClassOf|^rdfs:subClassOf [] }
路径表达式p1|p2
表示"match with any of these two relations"。运算符 ^
表示 "query the inverse of the relation"。所以如果我们把它们放在一起,上面的路径表达式就是 "match with any triples where the subject is ?c
and the relation is rdfs:subClassOf
, or where the relation rdfs:subClassOf
is inverted and thus the object matches with ?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 [] }
}
这可能会进一步缩短。当然,如果您对 ontology 非常了解,则可以进一步简化它(例如,如果您知道自己从不使用域或范围属性,则可以省略该位)。