lms*_*ant 14 rdf sparql jena arq tdb
我正在使用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 .
}
Run Code Online (Sandbox Code Playgroud)
这很好用,实际上非常快(<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 .
}
Run Code Online (Sandbox Code Playgroud)
我可以使用FILTER语法编写此查询的不区分大小写的版本,如下所示:
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") )
}
Run Code Online (Sandbox Code Playgroud)
但现在查询需要一分钟才能完成!有没有办法以更有效的方式编写不区分大小写的查询?
Man*_*res 18
从可以在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")
}
Run Code Online (Sandbox Code Playgroud)
这可能会更快,但一般来说,不希望任何三重商店的文本搜索具有出色的性能.三重商店非常擅长图形匹配,并且不太适合字符串匹配.
小智 2
使用 FILTER 查询的查询运行速度较慢的原因是因为 ?term 未绑定,它需要扫描 PSO 或 POS 索引以查找具有 rdfs:label 谓词的所有语句,并根据正则表达式过滤它们。当它绑定到具体资源时(在第一个示例中),它可以使用 OPS 或 POS 索引仅扫描具有 rdfs:label 谓词和指定对象资源的语句,这将具有低得多的基数。
此类文本搜索问题的常见解决方案是使用外部文本索引。在这种情况下,Jena 提供了一个名为LARQ的自由文本索引,它使用 Lucene 执行搜索并将结果与查询的其余部分连接起来。