【问题标题】:Query partial RDF graph by using SPARQL construct使用 SPARQL 构造查询部分 RDF 图
【发布时间】:2017-02-06 20:24:24
【问题描述】:

我正在使用 RDF4J 原生三元存储,其中存储了几个命名的图形/模型。在我的 Java 程序中,我试图通过使用 SPARQL CONSTRUCT 查询表单从命名图中检索部分图。部分图应由特定的整数值标识。

我存储的一个命名图如下所示,例如:

@prefix nif: <http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix app: <http://example.org/> .
@prefix onto: <http://example.org/ontology/> .

app:context#char=0,54 a nif:Context , nif:RFC5147String , nif:String ;
    nif:beginIndex "0"^^xsd:int ;
    nif:endIndex "54"^^xsd:int ;
    nif:isString "Barack Obama lives in Washington. He studied at Harvard" .

app:sentence#char=0,31 a nif:RFC5147String , nif:String , nif:Sentence ;
    onto:index "0"^^xsd:int ;
    nif:beginIndex "0"^^xsd:int ;
    nif:endIndex "31"^^xsd:int ;
    onto:entity app:entity#char=0,12 , app:entity#char=22,30 ;
    nif:referenceContext app:context#char=0,54 ;
    nif:nextSentence app:sentence#char=32,54 ;
    nif:anchorOf "Barack Obama lives in Washington." .

app:sentence#char=32,54 a nif:RFC5147String , nif:String , nif:Sentence ;
    onto:index "1"^^xsd:int ;
    nif:beginIndex "32"^^xsd:int ;
    nif:endIndex "54"^^xsd:int ;
    onto:entity app:entity#char=46,53 ;
    nif:referenceContext app:context#char=0,54 ;
    nif:previousSentence app:sentence#char=0,31 ;
    nif:anchorOf "He studied at Harvard." .

app:entity#char=0,12 a nif:RFC5147String , nif:String , nif:Phrase ;
    nif:beginIndex "0"^^xsd:int ;
    nif:endIndex "12"^^xsd:int ;
    onto:type "PERSON" ;
    nif:referenceContext app:context#char=0,54 ;
    nif:sentence app:sentence#char=0,31 ;
    nif:anchorOf "Barack Obama" .       

app:entity#char=22,30 a nif:RFC5147String , nif:String , nif:Phrase ;
    nif:beginIndex "22"^^xsd:int ;
    nif:endIndex "30"^^xsd:int ;
    onto:type "LOCATION" ;
    nif:referenceContext app:context#char=0,54 ;
    nif:sentence app:sentence#char=0,31 ;
    nif:anchorOf "Washington" .

app:entity#char=46,53 a nif:RFC5147String , nif:String , nif:Phrase ;
    nif:beginIndex "46"^^xsd:int ;
    nif:endIndex "53"^^xsd:int ;
    onto:type "ORGANIZATION" ;
    nif:referenceContext app:context#char=0,54 ;
    nif:sentence app:sentence#char=32,54 ;
    nif:anchorOf "Harvard" .

上图描述了两个使用 NLP 工具注释的句子。我想查询一个表示其中一个句子的子图,包括上下文、句子本身以及该特定句子的所有实体。

每个句子都有一个带有谓词onto:index 的索引,我想用它来识别一个特定的句子。属于一个句子的实体由onto:entity标识。

因此,所需的子图应包含主题 app:context#char=0,54app:sentence#char=0,31app:entity#char=0,12app:entity#char=22,30,以及它们各自的谓词和宾语。因此,它应该包含主题app:sentence#char=32,54app:entity#char=46,53

到目前为止,我的 SPARQL 查询如下所示:

PREFIX nif: <http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX app: <http://example.org/location#>
PREFIX onto: <http://example.org/ontology/>

CONSTRUCT {
    ?s ?p ?o .
}

WHERE {
    GRAPH app:12345 {
        ?s onto:index sentenceIndex .
    }
}

在 Java 中是这样的:

String nif: "http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#";
String xsd: "http://www.w3.org/2001/XMLSchema#";
String app = "http://example.org/location#" + modelID;
String onto = "http://example.org/ontology/";

    String sparqlQuery = "PREFIX nif: <" + nif + "> \n";
    sparqlQuery += "PREFIX xsd: <" + xsd + "> \n";
    sparqlQuery += "PREFIX onto: <" + onto + "> \n";
    sparqlQuery += "CONSTRUCT { \n";
    sparqlQuery += "    ?s ?p ?o . \n";
    sparqlQuery += "} \n";
    sparqlQuery += "WHERE { \n";
    sparqlQuery += "    GRAPH <" + app + "> { \n";
    sparqlQuery += "        ?s onto:index " + sentenceIndex + " . \n";
    sparqlQuery += "    } \n";
    sparqlQuery += "}";

sentenceIndex 表达式是一个 Java int 变量,用于传递实际的 onto:index 值。 app:location#12345 是上级命名图。

出于测试目的,上述查询最初应该只返回给定索引的整个句子主语,没有上下文或实体。但即使是这个简单的任务也失败了。它只是返回一个空的 RDF4J 模型。

现在,为了获得由onto:index 谓词标识的所需子图,正确的 SPARQL 查询是什么?

我不熟悉 SPARQL,因此非常感谢任何帮助。提前致谢!

【问题讨论】:

  • 此查询在语法上不正确,并且不会返回空模型 - 相反,查询将失败并出现语法错误(由前缀声明后面的句号引起)。这可能只是您的复制粘贴错误,并且很容易修复,但为了将来参考,请记住测试您在 SO 上发布的确切代码。
  • 很抱歉,这确实是复制和粘贴错误。我还编辑了我的帖子并添加了实际的 Java 代码。此代码没有编译错误,但返回一个空模型。

标签: java sparql rdf sesame rdf4j


【解决方案1】:
  1. 前缀在 SPARQL 中由点分隔,即查询不应在 RDF4J 中编译

  2. 为什么要将前缀图形 URI 放在尖括号中?要么你使用

    1. 完整的 URI &lt;http://example.org/location#12345&gt;
    2. 您更改app 的命名空间声明并使用前缀URI app:12345
PREFIX  app:  <http://example.org/location#>
PREFIX  xsd:  <http://www.w3.org/2001/XMLSchema#>
PREFIX  nif:  <http://persistence.unileipzig.org/nlp2rdf/ontologies/nif-core#>
PREFIX  onto: <http://example.org/ontology/>

CONSTRUCT 
  { 
    ?s ?p ?o .
  }
WHERE
  { GRAPH app:12345
      { ?s  onto:index  sentenceIndex }
  }

【讨论】:

  • 很抱歉,这是由我的实际 Java 代码和海龟数据混合导致的复制和粘贴错误。我已经编辑了我的原始帖子。但它仍然不起作用,只是返回一个空模型。
  • 您是否也更改了使用图形 URI 的方式?您的 Java 代码生成 GRAPH &lt;http://example.org/location#&gt; 并且在您的问题中您说图形是 app:location#12345
  • 是的,我在我的例子中改变了它。但它不应该在语义上产生任何影响,不是吗?
【解决方案2】:

为了使任务更容易,我建议您暂时不要使用前缀。首先尝试看看以下构造查询是否有效:

CONSTRUCT {
    ?s ?p ?o .
}

WHERE {
    GRAPH <http://example.org/location#12345> {
        ?s <http://example.org/ontology/index> 0 .
    }
}

如果这不起作用,请使用以下查询检查数据是否真的、真的、100% 在图表“http://example.org/location#12345”中:

SELECT * 
WHERE {
  ?s ?p ?o 

  optional{
  GRAPH ?g {
    ?s ?p ?o
  }
 }
}

此查询显示您的所有数据,以及数据位于哪个图表上。通过使用此查询,您还可以检查您查询的谓词 (index) 是否正确。

希望这可以帮助您找到问题,祝您 SPARQLing 愉快!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多