如何编写有效匹配字符串文字而忽略大小写的SPARQL查询
题
我正在使用Jena ARQ编写针对从Jena TDB读取的大型本体的SPARQL查询,以便查找与基于rdfs标签的概念相关联的类型:
SELECT DISTINCT ?type WHERE {
?x <http://www.w3.org/2000/01/rdf-schema#label> "aspirin" .
?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
}
这工作得很好,实际上很快(<1秒)。不幸的是,对于某些术语,我需要以不区分大小写的方式执行此查询。例如,因为标签 "Tylenol"
在本体中,但不是 "tylenol"
, ,下面的查询出现空:
SELECT DISTINCT ?type WHERE {
?x <http://www.w3.org/2000/01/rdf-schema#label> "tylenol" .
?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
}
我可以使用过滤器语法编写此查询的不区分大小写版本,如下所示:
SELECT DISTINCT ?type WHERE {
?x <http://www.w3.org/2000/01/rdf-schema#label> ?term .
?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
FILTER ( regex (str(?term), "tylenol", "i") )
}
但现在查询需要一分钟以上才能完成!有没有办法以更有效的方式编写不区分大小写的查询?
解决方案
具有过滤器查询的查询运行速度较慢的原因是因为?term is unbound它需要扫描PSO或POS索引以查找具有rdfs:label谓词的所有语句,并根据正则表达式过滤它们。当它绑定到具体资源(在第一个示例中)时,它可以使用OPS或POS索引仅扫描具有rdfs:label谓词和指定对象资源的语句,这将具有更低的基数。
这种类型的文本搜索问题的常见解决方案是使用外部文本索引。在这种情况下,Jena提供了一个名为 拉克, ,它使用Lucene执行搜索并将结果与查询的其余部分连接起来。
其他提示
从您可以在SPARQL中使用的所有可能的字符串运算符, regex
可能是最贵的。如果避免,查询可能会运行得更快 regex
你用 UCASE
或 LCASE
在测试的两侧代替。类似的东西:
SELECT DISTINCT ?type WHERE {
?x <http://www.w3.org/2000/01/rdf-schema#label> ?term .
?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
FILTER (lcase(str(?term)) = "tylenol")
}
这可能会更快,但一般来说,对于任何三重存储的文本搜索,不要期望有很好的性能。三重存储非常擅长图形匹配,而不是那么擅长字符串匹配。
不隶属于 StackOverflow