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”?
答案 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
这真的很奇怪。这是您的查询的修改版本,可以获得您正在寻找的结果。它使用值而不是 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)
}
我实际上是在清理字符串匹配,因为正则表达式可能比你需要的更强大。您只想检查值是否以给定的子字符串开头:
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 }
}