我想过滤特定关键字的SPARQL查询,同时排除其他关键字。我认为这可以通过FILTER (regex(str(?var),"includedKeyword","i") && !regex(str(?var),"excludedKeyword","i"))
轻松完成。它的工作原理没有“!”条件,但没有。我也分开了FILTER语句,但没有用。
我在http://europeana.ontotext.com/上使用了此查询:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX edm: <http://www.europeana.eu/schemas/edm/>
PREFIX ore: <http://www.openarchives.org/ore/terms/>
SELECT DISTINCT ?CHO
WHERE {
?proxy dc:subject ?subject .
FILTER ( regex(str(?subject),"gemälde","i") && !regex(str(?subject),"Fotografie","i") )
?proxy edm:type "IMAGE" .
?proxy ore:proxyFor ?CHO.
?agg edm:aggregatedCHO ?CHO; edm:country "germany".
}
但是我总是在第一行得到标题为“Gemäldegalerie”的结果,它有一个dc:主题为“Fotografie”(我想要排除的那个)。我认为问题在于,来自Europeana数据库的一个对象可以有多个dc:subject属性,所以它可能只查找其中一个属性而忽略其他属性。
有什么想法吗?非常感谢!
答案 0 :(得分:3)
问题是您的组合过滤器会检查?subject
的相同绑定。因此,如果?subject
的至少一个值与两个条件匹配(这几乎总是正确的,因为字符串“Gemäldegalerie”,例如,匹配您的第一个正则表达式并且与第二个正则表达不匹配),它会成功。
因此,对于否定条件,您需要制定检查所有可能值的内容,而不仅仅是一个特定值。您可以使用SPARQL的NOT EXISTS
函数执行此操作,例如:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX edm: <http://www.europeana.eu/schemas/edm/>
PREFIX ore: <http://www.openarchives.org/ore/terms/>
SELECT DISTINCT ?CHO
WHERE {
?proxy edm:type "IMAGE" .
?proxy ore:proxyFor ?CHO.
?agg edm:aggregatedCHO ?CHO; edm:country "germany".
?proxy dc:subject ?subject .
FILTER(regex(str(?subject),"gemälde","i"))
FILTER NOT EXISTS {
?proxy dc:subject ?otherSubject.
FILTER(regex(str(?otherSubject),"Fotografie","i"))
}
}
顺便说一下:由于您正在进行正则表达式检查,现在将它们与NOT EXISTS
运算符组合在一起,这对于查询处理器而言可能会非常昂贵。您可能想要考虑制定查询的其他方法(例如,使用确切的主题字符串来包含或排除以消除正则表达式),或者甚至查看SPARQL端点可能提供的一些非标准扩展(OWLIM)例如,运行Europeana端点的商店支持各种full-text-search extensions,但我不确定它们是否在Europeana端点中启用了。