如何在Sesame 2.7.7上的INSERT查询中自动生成新的实例标识符

时间:2013-11-29 13:49:23

标签: java rdf sesame

我在进行三联体的自动实例化时遇到了识别问题 使用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

谢谢!

1 个答案:

答案 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>