DBpedia SPARQL过滤器不适用于所有结果

时间:2016-04-06 02:48:24

标签: sparql dbpedia

FILTER NOT EXISTS允许在与OPTIONAL三元组合时获得一些结果。

我的查询:

SELECT DISTINCT * WHERE 
{
  {
    ?en rdfs:label "N'Djamena"@en .
    BIND("N'Djamena" AS ?name) .
  }
  UNION {
    ?en rdfs:label "Port Vila"@en .
    BIND("Port Vila" AS ?name) .
  }
  UNION {
    ?en rdfs:label "Atafu"@en .
    BIND("Atafu" AS ?name) .
  }
  FILTER NOT EXISTS { ?en rdf:type skos:Concept } .
  OPTIONAL { ?en owl:sameAs ?es . FILTER regex(?es, "es.dbpedia") .  }
  OPTIONAL { ?en owl:sameAs ?pt . FILTER regex(?pt, "pt.dbpedia") .  }
} 
LIMIT 100

此查询按预期获得三个位置,但它也会拉回“类别:Atafu”,这应该通过“rdf:type skos:Concept”过滤掉。

如果在没有OPTIONAL行的情况下使用,我会得到预期的三个位置。当与这些条款非选择性地一起使用时,我只获得两个国家,因为Atafu没有葡萄牙语页面。

我也可以将FILTER NOT EXISTS语句移动到每个UNION的国家/地区块中,但这似乎会损害服务器的响应时间。

为什么FILTER NOT EXISTS子句会在Category:Port_Vila后面过滤掉“类别:N'Djamena”和OPTIONAL但不会过滤“类别:Atafu”?

1 个答案:

答案 0 :(得分:3)

我真的不知道为什么你的查询不起作用。我不得不把它归结为一些奇怪的Virtuoso事情。绝对会有一些奇怪的事情发生。例如,如果您删除姓氏的绑定,您将获得您期望的资源:

SELECT DISTINCT * WHERE 
{
  {
    ?en rdfs:label "N'Djamena"@en .
    BIND("N'Djamena" AS ?name) .
  }
  UNION {
    ?en rdfs:label "Port Vila"@en .
    BIND("Port Vila" AS ?name) .
  } 
  UNION {
    ?en rdfs:label "Atafu"@en .
  }
  FILTER NOT EXISTS { ?en rdf:type skos:Concept }
  OPTIONAL { ?en owl:sameAs ?es . FILTER regex(?es, "es.dbpedia") }
  OPTIONAL { ?en owl:sameAs ?pt . FILTER regex(?pt, "pt.dbpedia") .  }
} 
LIMIT 100

SPARQL results

这真的很奇怪。这是您的查询的修改版本,可以获得您正在寻找的结果。它使用而不是 union ,这使查询更简单。但它应该在逻辑上是等价的,所以我不确定它为什么会有所作为。

select distinct * where {
  values ?label { "N'Djamena"@en "Port Vila"@en "Atafu"@en }
  ?en rdfs:label ?label .
  optional { ?en owl:sameAs ?pt . filter regex(?pt, "pt.dbpedia") }
  optional { ?en owl:sameAs ?es . filter regex(?es, "es.dbpedia") }
  filter not exists { ?en a skos:Concept }
  bind(str(?label) as ?name)
}

SPARQL results

我实际上是在清理字符串匹配,因为正则表达式可能比你需要的更强大。您只想检查值是否以给定的子字符串开头:

select ?en ?label (str(?label) as ?name) ?es ?pt where {
  values ?label { "N'Djamena"@en "Port Vila"@en "Atafu"@en }
  ?en rdfs:label ?label .
  optional { ?en owl:sameAs ?pt . filter strstarts(str(?pt), "http://pt.dbpedia") }
  optional { ?en owl:sameAs ?es . filter strstarts(str(?es), "http://es.dbpedia") }
  filter not exists { ?en a skos:Concept }
}

SPARQL results