DBpedia SPARQL过滤器不适用于所有结果 [英] DBpedia SPARQL filter does not apply to all results

查看:102
本文介绍了DBpedia SPARQL过滤器不适用于所有结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不存在过滤器 OPTIONAL 三元组结合使用时,可以通过一些结果。

A FILTER NOT EXISTS allows some results through when combined with OPTIONAL triples.

我的查询:

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将其过滤掉。

This query gets the three places as expected, but it also pulls back "Category:Atafu", which should be filtered out by virtue of having "rdf:type skos:Concept".

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

When used without the OPTIONAL lines, I get the three places expected. When used with those clauses non-optionally, I get only two of the countries, because Atafu doesn't have a page in Portuguese.

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

I can also move the FILTER NOT EXISTS statement into each of the UNION'd country blocks, but that seems to hurt the server's response time.

为什么 FILTER不存在子句会过滤掉 Category:N'Djamena和 Category:Port_Vila 而不是 Category :Atafu,然后跟着 OPTIONAL

Why does the FILTER NOT EXISTS clause filter out "Category:N'Djamena" and Category:Port_Vila but not "Category:Atafu" when followed by OPTIONAL?

推荐答案

我真的没有了解为什么您的查询无效。我必须把它归结为一些Virtuoso怪异的东西。肯定有奇怪的事情发生。例如,如果删除姓氏的 bind ,您将获得所需的资源:

I really have no idea why your query doesn't work. I'd have to chalk it up to some weird Virtuoso thing. There's definitely something strange going on. For instance, if you remove the bind for the last name, you'll get the resources you're expecting:

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结果

这真的很奇怪。这是查询的修改版本,可获取您想要的结果。它使用代替 union ,这使查询更简单。不过,它在逻辑上应该是等效的,所以我不确定为什么会有所不同。

It's really pretty weird. Here's a modified version of your query that gets the results you're looking for. It uses values instead of union, which makes the query simpler. It should be logically equivalent, though, so I'm not sure why it makes a difference.

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结果

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

I'd actually clean up the string matching though, since regular expressions are probably more power than you need here. You just want to check whether the value starts with a given substring:

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结果

这篇关于DBpedia SPARQL过滤器不适用于所有结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆