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

DBpedia SPARQL filter does not apply to all results

A FILTER NOT EXISTSOPTIONAL 三元组组合时允许某些结果通过。

我的查询:

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

这个查询得到了预期的三个地方,但是它也拉回了"Category:Atafu",应该凭借"rdf:type skos:Concept"过滤掉了。

在没有 OPTIONAL 行的情况下使用时,我得到了预期的三个位置。当非可选地与这些子句一起使用时,我只得到两个国家,因为 Atafu 没有葡萄牙语页面。

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

为什么 FILTER NOT EXISTS 子句过滤掉 "Category:N'Djamena" 和 Category:Port_Vila 而不是 "Category:Atafu" 后跟 OPTIONAL

我真的不知道为什么你的查询不起作用。我不得不将其归因于一些奇怪的 Virtuoso 事情。肯定有什么奇怪的事情发生了。例如,如果您删除姓氏的 bind,您将获得您期望的资源:

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

这真的很奇怪。这是您的查询的修改版本,可获得您要查找的结果。它使用 values 而不是 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