根据URI前缀排除DBpedia SPARQL查询的结果

时间:2013-09-27 07:15:01

标签: sparql dbpedia

如何在使用DBpedia SPARQL endpoint时排除一组概念?我正在使用以下基本查询来获取概念列表:

SELECT DISTINCT ?concept
WHERE {
    ?x a ?concept
}
LIMIT 100

SPARQL Results

这给了我100个概念的清单。我想排除属于YAGO类/组的所有概念(即,其IRI以http://dbpedia.org/class/yago/开头)。我可以过滤掉这样的个人概念:

SELECT DISTINCT ?concept
WHERE {
    ?x a ?concept
    FILTER (?concept != <http://dbpedia.org/class/yago/1950sScienceFictionFilms>)
}
LIMIT 100

SPARQL Results

但我似乎无法理解的是如何从我的结果中排除所有YAGO子类?我尝试使用这样的*,但这没有取得任何成果:

FILTER (?concept != <http://dbpedia.org/class/yago/*>)

更新

这个带regex的查询似乎可以解决这个问题,但它确实非常非常缓慢而且难看。我真的很期待一个更好的选择。

SELECT DISTINCT ?type WHERE {
  [] a ?type
  FILTER( regex(str(?type), "^(?!http://dbpedia.org/class/yago/).+"))
}
ORDER BY ASC(?type)
LIMIT 10

1 个答案:

答案 0 :(得分:9)

看起来有点尴尬,但是关于转换为字符串并进行一些基于字符串的检查的评论可能是在正确的轨道上。您可以使用SPARQL 1.1函数strstarts

更有效地执行此操作
SELECT DISTINCT ?concept
WHERE {
    ?x a ?concept
    FILTER ( !strstarts(str(?concept), "http://dbpedia.org/class/yago/") )
}
LIMIT 100

SPARQL Results

另一种选择是找到顶级YAGO类,并排除那些rdfs:subClassOf顶级类的概念。从长远来看,这可能是一个更好的解决方案(因为它不需要转换为字符串,而且它基于图形结构)。不幸的是,它看起来并不像一个与owl:Thing相当的顶级YAGO类。我刚刚从DBpedia's download page下载了YAGO类型层次结构并运行了此查询,该查询要求没有超类的类:

prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select distinct ?root where {
  [] rdfs:subClassOf ?root 
  filter not exists { ?root rdfs:subClassOf ?superRoot }
}

我得到了这九个结果:

----------------------------------------------------------------
| root                                                         |
================================================================
| <http://dbpedia.org/class/yago/YagoLegalActorGeo>            |
| <http://dbpedia.org/class/yago/WaterNymph109550125>          |
| <http://dbpedia.org/class/yago/PhysicalEntity100001930>      |
| <http://dbpedia.org/class/yago/Abstraction100002137>         |
| <http://dbpedia.org/class/yago/YagoIdentifier>               |
| <http://dbpedia.org/class/yago/YagoLiteral>                  |
| <http://dbpedia.org/class/yago/YagoPermanentlyLocatedEntity> |
| <http://dbpedia.org/class/yago/Thing104424418>               |
| <http://dbpedia.org/class/yago/Dryad109551040>               |
----------------------------------------------------------------

鉴于YAGO概念不像其他概念那样具有结构性,看起来基于字符串的方法在这种情况下可能是最好的。但是,如果你愿意,你可以这样做一个非基于字符串的查询,它要求100个概念,不包括那些将这9个结果中的一个作为超类的概念:

select distinct ?concept where {
  [] a ?concept .
  filter not exists {
    ?concept rdfs:subClassOf* ?super .
    values ?super { 
      yago:YagoLegalActorGeo
      yago:WaterNymph109550125
      yago:PhysicalEntity100001930
      yago:Abstraction100002137
      yago:YagoIdentifier
      yago:YagoLiteral
      yago:YagoPermanentlyLocatedEntity
      yago:Thing104424418
      yago:Dryad109551040
    }
  }
}
limit 100

SPARQL Results

我不确定哪个最终会更快。第一个需要转换为字符串,而strstarts如果以天真的方式实现,则必须在每个概念中消耗http://dbpedia.org/class/之前不匹配。第二个需要进行九次比较,如果IRI被实习,则只是对象身份检查。这是一个有待进一步调查的有趣问题。