我在进行三联体的自动实例化时遇到了识别问题 使用SPARQL查询。让我们通过这个例子来看问题。
假设我们有以下表示人及其除草关系的三元组。
ns:Person rdf:type owl:Class
ns:Man rdfs:subClassOf ns:Person
ns:Woman rdfs:subClassOf ns:Person
ns:Family rdf:type owl:Class
ns:jean rdf:type ns:Man
ns:roger rdf:type ns:Man
ns:chris rdf:type ns:Woman
ns:sofy rdf:type ns:Woman
ns:chloe rdf:type ns:Woman
ns:jean ns:isMarriedWith ns:chris
ns:roger ns:isMarriedWith ns:chloe
好了,现在我们想要使用两个人结婚时的家庭规则来自动建立家庭。
IF (ns:A ns:isMarriedWith ns:B)
THEN (ns:f rdf:type Family)
AND (ns:f ns:contains A)
AND (ns:f ns:contains B)
这里是我建议在http sesame存储库上执行的Java代码。
Repository myRepository = new HTTPRepository(serverURL, repositoryId);
myRepository.initialize();
RepositoryConnection con = myRepository.getConnection();
query = "INSERT {"
+ " ns:f0 rdf:type ns:Family ."
+ " ns:f0 ns:contains ?p ."
+ " ns:f0 ns:contains ?q ."
+ "}"
+ "WHERE { "
+ " ?p ns:isMarriedWith ?q ."
+ "}";
Update update = con.prepareUpdate(QueryLanguage.SPARQL, query);
update.execute();
以下是插入的三元组
ns:f0 rdf:type ns:Family
ns:f0 ns:contains ns:jean
ns:f0 ns:contains ns:chris
ns:f0 ns:contains ns:roger
ns:f0 ns:contains ns:chloe
此结果不正确,因为只创建了一个系列。问题是,在WHERE子句匹配的任何时候,familly实例的标识都不会改变。
我如何调整上面的代码,以便有正确的响应。
ns:f0 rdf:type ns:Family
ns:f0 ns:contains ns:jean
ns:f0 ns:contains ns:chris
ns:f1 rdf:type ns:Family
ns:f1 ns:contains ns:roger
ns:f1 ns:contains ns:chloe
谢谢!
答案 0 :(得分:2)
如果您提供的数据和代码我们可以使用而必须添加大量内容以使其完整,那么 更容易回答此类问题。例如,提供完整的RDF文档。你的数据是这样的(在Turtle中):
@prefix ns: <http://stackoverflow.com/q/20287293/1281433/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
ns:Person a owl:Class .
ns:Man rdfs:subClassOf ns:Person .
ns:Woman rdfs:subClassOf ns:Person .
ns:Family a owl:Class .
ns:jean a ns:Man .
ns:roger a ns:Man .
ns:chris a ns:Woman .
ns:sofy a ns:Woman .
ns:chloe a ns:Woman .
ns:jean ns:isMarriedWith ns:chris .
ns:roger ns:isMarriedWith ns:chloe .
在您的SPARQL查询中,不清楚f0
是什么,因为它不是合法的SPARQL语法,但根据您对问题的描述,您会得到以下内容。我已经更改为construct
查询,以便我们可以查看查询结果并查看构造的三元组,这与插入的三元组相同。这样可以更容易地看到发生了什么。
prefix ns: <http://stackoverflow.com/q/20287293/1281433/>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <urn:ex:>
construct {
:f0 a ns:Family . # This can be written as
:f0 ns:contains ?p . # :f0 a ns:Family ; ns:contains ?p, ?q .
:f0 ns:contains ?q . #
}
where {
?p ns:isMarriedWith ?q .
}
现在,您的问题是,当您对该数据运行此查询时,您会得到如下结果:
:f0 a ns:Family ;
ns:contains ns:chris , ns:jean , ns:chloe , ns:roger .
其中一个系列包含所有四个人,但您希望每个系列都有一个不同的系列。诀窍是用空白节点替换常量 :f0
,这对于查询中的每个匹配都是唯一的。您只需将:f0
更改为_:f0
:
_:f0 a ns:Family .
_:f0 ns:contains ?p .
_:f0 ns:contains ?q .
但是我更愿意使用我们可以获得的更多的语法糖并写下来:
[ a ns:Family ; ns:contains ?p, ?q ]
所以我们有:
prefix ns: <http://stackoverflow.com/q/20287293/1281433/>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <urn:ex:>
construct {
_:f0 a ns:Family ; ns:contains ?p, ?q .
}
where {
?p ns:isMarriedWith ?q .
}
此查询的结果包含两个不同的系列:
@prefix : <urn:ex:> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ns: <http://stackoverflow.com/q/20287293/1281433/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
[ a ns:Family ;
ns:contains ns:chris , ns:jean
] .
[ a ns:Family ;
ns:contains ns:chloe , ns:roger
] .
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ns="http://stackoverflow.com/q/20287293/1281433/"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns="urn:ex:"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<ns:Family>
<ns:contains rdf:resource="http://stackoverflow.com/q/20287293/1281433/chris"/>
<ns:contains rdf:resource="http://stackoverflow.com/q/20287293/1281433/jean"/>
</ns:Family>
<ns:Family>
<ns:contains rdf:resource="http://stackoverflow.com/q/20287293/1281433/chloe"/>
<ns:contains rdf:resource="http://stackoverflow.com/q/20287293/1281433/roger"/>
</ns:Family>
</rdf:RDF>