【问题标题】:How to query SUMO ontology using SPARQL如何使用 SPARQL 查询 SUMO 本体
【发布时间】:2013-09-17 14:00:11
【问题描述】:

我正在使用我想用 SPARQL 查询的 SUMO 本体。 SUMO 中的典型条目(例如,对于一个城市)如下所示:

<owl:Thing rdf:ID="MadridSpain">
 <rdfs:isDefinedBy rdf:resource="http://www.ontologyportal.org/SUMO.owl"/>
 <rdf:type rdf:resource="#City"/>
 <owl:comment xml:lang="en">The City of Madrid in Spain.</owl:comment>
 <geographicSubregion rdf:resource="#Spain" />
 <externalImage rdf:datatype="xsd:anyURI">[...]</externalImage>
 <rdfs:label xml:lang="en">madrid spain</rdfs:label>
</owl:Thing>

如果我想从本体中获取所有城市,我使用这个示例查询(效果很好):

String prefix = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> "
              + "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>";
String rdq = prefix + "SELECT ?N ?O WHERE {?N rdf:type <http://www.ontologyportal.or/SUMO.owl#City>}";

当我想过滤结果时,我的问题就开始了。假设我只想要西班牙地理子区域的所有城市。首先,我尝试通过分析 Java 和 Jena 中的所有结果来解决这个问题,这需要花费大量时间(每个结果需要 5-10 秒,大约 10000 个结果)。

Query myQuery = QueryFactory.create(rdq);
QueryExecution qexec = QueryExecutionFactory.create(myQuery, owlModel);
try {
 ResultSet results = qexec.execSelect();
 for (; results.hasNext();) {
  QuerySolution sol = results.nextSolution();
  Resource res = sol.getResource("N");
  StmtIterator it = res.listProperties();

  while(it.hasNext()){
   Statement state = it.next();
   //Doing some filtering
   System.out.println("predicate: " + state.getPredicate().toString());
   System.out.println("subject: " + state.getSubject().toString());
   System.out.println("object: " + state.getObject().toString());
  }
 }
}catch (Exception e) {
 e.printStackTrace();
 System.err.println("Query Error " + e.getMessage());
}

当然这不是很有效,它必须通过使用正确的查询以更简单的方式存在。但目前我坚持定义这样的查询。我尝试了以下方法,但它们都不起作用。

SELECT ?N ?O WHERE { ?N rdf:type <http://www.ontologyportal.org/SUMO.owl#City> . 
 { SELECT ?N WHERE { (rdf:type ?b rdf:statement) .
 (rdf:Predicate ?b <http://www.ontologyportal.org/SUMO.owl#geographicSubregion>) .
 (rdf:Object ?b <http://www.ontologyportal.org/SUMO.owl#Spain>) } } }

SELECT ?N ?O WHERE { (rdf:statement ?b) .
 (rdf:Predicate ?b <http://www.ontologyportal.org/SUMO.owl#geographicSubregion>) . 
 (rdf:Object ?b <http://www.ontologyportal.org/SUMO.owl#Spain>) . }";

有人知道如何创建一个查询来获取一个国家/地区内的所有城市吗?

【问题讨论】:

  • 您在这方面取得了进展吗?几年前我曾短暂接触过 SUMO,并不知道有 OWL 翻译,所以这很有趣。如果到目前为止的答案没有帮助,您还遇到了哪些其他问题?
  • 您的解决方案效果很好,并且 +1 以获得最佳答案。
  • 很高兴能帮上忙!正如我所说,我不知道 SUMO 的 OWL 翻译,所以这对我来说是一个好消息。感谢您的询问!

标签: java sparql jena ontology


【解决方案1】:

我使用您提供的 RDF 制作了一个可以查询的最小 RDF 文件:

<rdf:RDF xmlns="http://www.ontologyportal.org/SUMO.owl#"
         xml:base="http://www.ontologyportal.org/SUMO.owl"
         xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
         xmlns:owl="http://www.w3.org/2002/07/owl#"
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <owl:Thing rdf:ID="MadridSpain">
    <rdfs:isDefinedBy rdf:resource="http://www.ontologyportal.org/SUMO.owl"/>
    <rdf:type rdf:resource="#City"/>
    <owl:comment xml:lang="en">The City of Madrid in Spain.</owl:comment>
    <geographicSubregion rdf:resource="#Spain" />
    <externalImage rdf:datatype="xsd:anyURI">[...]</externalImage>
    <rdfs:label xml:lang="en">madrid spain</rdfs:label>
  </owl:Thing>
</rdf:RDF>

SPARQL 是一种用于匹配 RDF 图中数据的查询语言。 RDF 图中的边是三元组,形式为主谓宾 的简单语句。您正在匹配一个三元组。

?N rdf:type <http://www.ontologyportal.org/SUMO.owl#City>

如果您为sumo: 定义前缀,您的查询将更容易编写,因此我们最终会得到(也将?N 重命名为?city):

prefix sumo: <http://www.ontologyportal.org/SUMO.owl#>
select ?city where { 
  ?city rdf:type sumo:City .
}

如您所见,这会选择所有城市。现在你只需要匹配一个额外的三元组,所以我们只需将它添加到查询中:

prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix sumo: <http://www.ontologyportal.org/SUMO.owl#>
select ?city where { 
  ?city rdf:type sumo:City .
  ?city sumo:geographicSubregion sumo:Spain .
}

为了使这看起来更好,可以应用两个缩写。首先,在 SPARQL 中,rdf:type 可以写成a,因为它很常见(然后我们也不需要定义前缀)。其次,当您有多个具有相同主题的三元组时,您可以列出用分号分隔的 谓词对象 部分。我们最终得到了

prefix sumo: <http://www.ontologyportal.org/SUMO.owl#>
select ?city where { 
  ?city a sumo:City ;
        sumo:geographicSubregion sumo:Spain .
}

当我使用 Jena 的命令行工具对上述 RDF 运行此程序时,我得到以下结果:

$ arq --data sumo.rdf --query query.sparql
--------------------
| city             |
====================
| sumo:MadridSpain |
--------------------

为什么其他查询不起作用

你想在这样的事情上做什么

(rdf:type ?b rdf:statement) .
(rdf:Predicate ?b <http://www.ontologyportal.org/SUMO.owl#geographicSubregion>) .
(rdf:Object ?b <http://www.ontologyportal.org/SUMO.owl#Spain>)

正在使用 RDF 物化词汇。首先,语法需要是

?b a rdf:Statement ;
   rdf:subject ?city ;
   rdf:predicate sumo:geographicSubregion ;
   rdf:object sumo:Spain .

为了匹配您需要回答查询的表单的具体化三元组。但是,这个查询要求在指定形式的图中有四个三元组,而那些 不在 模型中。仅仅因为图中有一个三元组并不意味着它是一个具体化的版本。 (毕竟,因为用于具体化第一个三元组的所有三元组也必须具体化,然后那些三元组也必须具体化,依此类推。)SPARQL 只允许您查询实际存在于数据中的三元组。

【讨论】:

  • 感谢您的精彩评论。您的解决方案效果很好。也感谢你不遗余力地解释我的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多