首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用SPARQL查询SUMO本体

如何使用SPARQL查询SUMO本体
EN

Stack Overflow用户
提问于 2013-09-17 14:00:11
回答 1查看 1.1K关注 0票数 4

我使用的是相扑本体,我想用SPARQL查询它。相扑中的一个典型条目,例如,对于一个城市来说,看起来如下:

代码语言:javascript
复制
<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>

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

代码语言:javascript
复制
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>}";

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

代码语言:javascript
复制
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());
}

当然,这并不是真正有效的,而且通过使用正确的查询,它必须存在一种更简单的方法。但目前,我仍然无法定义这样的查询。我试过以下几种,但都不起作用。

代码语言:javascript
复制
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>) . }";

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-17 15:10:49

我使用您提供的RDF来创建一个最小的RDF文件,我可以对该文件进行查询:

代码语言:javascript
复制
<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图中的边是三元组,是表单主谓对象的简单语句。你是和一个三重匹配的。

代码语言:javascript
复制
?N rdf:type <http://www.ontologyportal.org/SUMO.owl#City>

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

代码语言:javascript
复制
prefix sumo: <http://www.ontologyportal.org/SUMO.owl#>
select ?city where { 
  ?city rdf:type sumo:City .
}

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

代码语言:javascript
复制
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,因为它非常常见(然后我们也不需要定义前缀)。其次,当同一个主题有多个三元组时,可以列出由分号分隔的谓词对象部分。我们最后

代码语言:javascript
复制
prefix sumo: <http://www.ontologyportal.org/SUMO.owl#>
select ?city where { 
  ?city a sumo:City ;
        sumo:geographicSubregion sumo:Spain .
}

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

代码语言:javascript
复制
$ arq --data sumo.rdf --query query.sparql
--------------------
| city             |
====================
| sumo:MadridSpain |
--------------------

为什么其他查询不起作用

你在这种事情上想做的事

代码语言:javascript
复制
(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物化词汇表。首先,语法需要

代码语言:javascript
复制
?b a rdf:Statement ;
   rdf:subject ?city ;
   rdf:predicate sumo:geographicSubregion ;
   rdf:object sumo:Spain .

以匹配回答查询所需的窗体的一个具体化的三重。但是,此查询要求指定表单的图形中有四个三元组,而模型中没有这些三元组。仅仅因为三元组在图中并不意味着它的具体化版本。(毕竟,因为用于还原第一个三元组的所有三元组也必须被具体化,然后这些三元组也会被具体化,等等)。SPARQL只允许查询数据中的三元组。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18851992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档