16

我正在使用 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 .
}

我可以使用 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") )
}

但是现在查询需要一分钟才能完成!有没有办法以更有效的方式编写不区分大小写的查询?

4

2 回答 2

19

在您可以在 SPARQL 中使用的所有可能的字符串运算符中,regex可能是最昂贵的一个。如果您避免regex使用UCASEorLCASE在测试的两侧代替,您的查询可能会运行得更快。就像是:

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")
}

这可能会更快,但通常不要期望任何三重存储的文本搜索性能都很好。三重存储非常擅长图匹配,但不太擅长字符串匹配。

于 2012-05-19T00:35:33.123 回答
2

使用 FILTER 查询的查询运行速度较慢的原因是 ?term 未绑定,它需要扫描 PSO 或 POS 索引以查找所有带有 rdfs:label 谓词的语句并根据正则表达式过滤它们。当它绑定到具体资源(在您的第一个示例中)时,它可以使用 OPS 或 POS 索引仅扫描具有 rdfs:label 谓词和指定对象资源的语句,这将具有低得多的基数。

此类文本搜索问题的常见解决方案是使用外部文本索引。在这种情况下,Jena 提供了一个名为LARQ的自由文本索引,它使用 Lucene 执行搜索并将结果与​​查询的其余部分连接起来。

于 2012-05-31T20:44:37.203 回答