在 SPARQL 中删除不需要的超类答案
Removing unwanted superclass answers in SPARQL
我有一个 OWL 文件,其中包含一个分类层次结构,我想编写一个查询,其中答案包括每个个体及其直接分类父级。这是一个示例(完整的查询比较混乱)。
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf: <http:://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix : <urn:ex:> .
:fido rdf:type :Dog .
:Dog rdfs:subClassOf :Mammal .
:Mammal rdfs:subClassOf :Vertebrate .
:Vertebrate rdfs:subClassOf :Animal .
:fido :hasToy :bone
:kitty rdf:type :Cat .
:Cat rdfs:subClassOf :Mammal .
:kitty :hasToy :catnipMouse .
并且此查询符合我的要求。
prefix rdf: <http:://www.w3.org/1999/02/22-rdf-syntax-ns#> .
prefix : <urn:ex:> .
SELECT ?individual ?type
WHERE {
?individual :hasToy :bone .
?individual rdf:type ?type .
}
问题是我宁愿使用经过推理的 OWL 文件版本,它包含额外的语句:
:fido rdf:type :Mammal .
:fido rdf:type :Vertebrate .
:fido rdf:type :Animal .
:kitty rdf:type :Mammal .
:kitty rdf:type :Vertebrate .
:kitty rdf:type :Animal .
现在查询结果是关于 Fido 是哺乳动物等的额外答案。我可以放弃使用文件的合理版本,或者,因为 SPARQL 查询是从 java 调用的,我可以做一堆额外的查询来找到出现的最少包含类型。我的问题是是否有一个合理的纯 SPARQL 解决方案来只返回 Dog 解决方案。
一个通用的解决方案是确保只请求 direct 类型。 A class C
是实例的直接类型 X
if:
X
的类型是 C
- 没有
C'
这样的:
X
的类型是 C'
C'
是 C
的子class
C'
不等于 C
(最后一个条件是必要的,顺便说一句,因为在 RDF/OWL 中,子 class 关系是自反的:每个 class 都是子 class本身)
在 SPARQL 中,这会变成这样:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <urn:ex:> .
SELECT ?individual ?type
WHERE {
?individual :hasToy :bone .
?individual a ?type .
FILTER NOT EXISTS { ?individual a ?other .
?other rdfs:subClassOf ?type .
FILTER(?other != ?type)
}
}
根据您用来执行这些查询的API/triplestore/library,可能还有其他特定于工具的解决方案。例如,Sesame API(披露:我在 Sesame 开发团队)可以选择禁用针对单个查询的推理:
TupleQuery query = conn.prepareTupleQuery(SPARQL, "SELECT ...");
query.setIncludeInferred(false);
TupleQueryResult result = query.evaluate();
Sesame 还提供了一个可选的附加推理器(称为 'direct type inferencer'),它引入了您可以查询的附加 'virtual' 属性,例如 sesame:directType
、sesame:directSubClassOf
等。其他工具无疑也有类似的选项。
我有一个 OWL 文件,其中包含一个分类层次结构,我想编写一个查询,其中答案包括每个个体及其直接分类父级。这是一个示例(完整的查询比较混乱)。
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf: <http:://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix : <urn:ex:> .
:fido rdf:type :Dog .
:Dog rdfs:subClassOf :Mammal .
:Mammal rdfs:subClassOf :Vertebrate .
:Vertebrate rdfs:subClassOf :Animal .
:fido :hasToy :bone
:kitty rdf:type :Cat .
:Cat rdfs:subClassOf :Mammal .
:kitty :hasToy :catnipMouse .
并且此查询符合我的要求。
prefix rdf: <http:://www.w3.org/1999/02/22-rdf-syntax-ns#> .
prefix : <urn:ex:> .
SELECT ?individual ?type
WHERE {
?individual :hasToy :bone .
?individual rdf:type ?type .
}
问题是我宁愿使用经过推理的 OWL 文件版本,它包含额外的语句:
:fido rdf:type :Mammal .
:fido rdf:type :Vertebrate .
:fido rdf:type :Animal .
:kitty rdf:type :Mammal .
:kitty rdf:type :Vertebrate .
:kitty rdf:type :Animal .
现在查询结果是关于 Fido 是哺乳动物等的额外答案。我可以放弃使用文件的合理版本,或者,因为 SPARQL 查询是从 java 调用的,我可以做一堆额外的查询来找到出现的最少包含类型。我的问题是是否有一个合理的纯 SPARQL 解决方案来只返回 Dog 解决方案。
一个通用的解决方案是确保只请求 direct 类型。 A class C
是实例的直接类型 X
if:
X
的类型是C
- 没有
C'
这样的:X
的类型是C'
C'
是C
的子class
C'
不等于C
(最后一个条件是必要的,顺便说一句,因为在 RDF/OWL 中,子 class 关系是自反的:每个 class 都是子 class本身)
在 SPARQL 中,这会变成这样:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <urn:ex:> .
SELECT ?individual ?type
WHERE {
?individual :hasToy :bone .
?individual a ?type .
FILTER NOT EXISTS { ?individual a ?other .
?other rdfs:subClassOf ?type .
FILTER(?other != ?type)
}
}
根据您用来执行这些查询的API/triplestore/library,可能还有其他特定于工具的解决方案。例如,Sesame API(披露:我在 Sesame 开发团队)可以选择禁用针对单个查询的推理:
TupleQuery query = conn.prepareTupleQuery(SPARQL, "SELECT ...");
query.setIncludeInferred(false);
TupleQueryResult result = query.evaluate();
Sesame 还提供了一个可选的附加推理器(称为 'direct type inferencer'),它引入了您可以查询的附加 'virtual' 属性,例如 sesame:directType
、sesame:directSubClassOf
等。其他工具无疑也有类似的选项。