如何为 SPARQL 查询设置排序规则?

How do you set the Collation for a SPARQL query?

我是一名使用 MarkLogic 数据库的 Java 开发人员。我的代码的一个关键功能是它能够动态生成 4-6 个 SPARQL 查询并通过 HTTP GET 请求 运行 它们。每个的结果加在一起然后返回。我现在需要对这些结果进行一致排序。

由于我对每个查询的结果进行分页(使用 LIMIT 和 OFFSET 语句),每个查询都有自己的 ORDER BY 语句。如果不在查询中嵌入排序,结果页面将乱序返回。

但是,每个查询 returns 都有自己的结果,这些结果是单独排序的,需要合并到一个排序列表中。我的偏好是字母数字排序,它在考虑大小写之前考虑字符,并将空值和空值排序到最后。 (示例:“0123456789AaBbCc…WwXxYyZz”)

我已经在我的 Java 代码中使用自定义比较方法完成了此操作,但我最近 运行 遇到了一个问题:我的结果仍然没有返回排序。我遇到的问题源于这样一个事实,即我的自定义排序方案与 SPARQL 使用的排序方案完全不同,导致了一组明显未排序的结果。虽然我考虑过在返回结果之前从头开始对结果进行排序,而不是假设 MarkLogic 返回排序后的结果,但这似乎是不必要的浪费,甚至可能无法解决我的问题。

在我的研究中,我还没有找到任何方法来为 SPARQL 设置排序规则,也没有找到编写自定义排序规则的方法。此页面上的文档 (https://www.w3.org/TR/rdf-sparql-query/#modOrderBy) specifically states that SPARQL’s ORDER BY is based on a comparison method driven by XPATH’s fn:compare. That function references this page (https://www.w3.org/TR/xpath-functions/#collations) 特别提到了用于指定排序规则以及使用 Unicode 排序规则算法的替代实现的选项。我找不到任何详细说明如何实际执行此操作的信息。

简而言之,我有什么方法可以操纵或控制 SPARQL 查询比较字符以影响最终顺序的方式吗?

如果我理解您的要求,您想使用 ORDER BY、OFFSET 和 LIMIT 来 select 您要显示的 结果,然后您需要另一个 ORDER BY 来确定显示这些结果的顺序(这可能与您用来 select 它们的顺序不同)。您可以使用嵌套查询来做到这一点:

select ?result {
  { select ?result where {
      #-- ...
    }
    order by #-- ...
    offset #-- ...
    limit #-- ...
  }
}
order by #-- ...

自定义排序的支持不是很多,但是你可以在顺序表达式中使用函数,你可以提供多个表达式先按一个事物排序,然后由另一个。在您的情况下,看起来您可能想要执行 order lcase(?value) 之类的操作以不区分大小写地进行排序。 (当然,这并不完美。例如,我不清楚是否要对数字前缀进行数字排序(例如,顺序应该是 1、10、2 还是 1、2、10)。 )

我刚刚从 SPARQL 实施者那里得到了明确的答复。

SPARQL 规范并未真正解决排序规则问题。 MarkLogic 使用 unicode 代码点排序规则进行 SPARQL 排序。

但是,我们需要了解您的要求。如您所知,MarkLogic 支持所有类型的排序规则,并且这种支持内置于支持 SPARQL 的代码中——我们只是没有公开关于如何利用 SPARQL 排序规则的接口。

MarkLogic 正在关注此线程,所以请随时提出请求,或许可以建议您考虑如何从查询中访问排序规则,我们会看到的。

我就此联系了 MarkLogic 的 Kevin Morgan,他提供了极大的帮助。昨天我们举行了一次 WebEx 会议,讨论了该问题的各种解决方案,会议进展顺利。

他们的工程师证实,到目前为止,还没有办法强制 SPARQL 使用特定的排序顺序。他们针对我的问题提出了两个有希望的解决方案:

• 在您的文档中嵌入您的三元组并利用文档搜索和范围索引:虽然这适用于多个系统设计,但它不适用于我们的设计。排序和分页属于产品升级,我们不能要求我们的客户完全 re-ingest 他们的数据,以便我们可以应用这个新标准。

• 将 SPARQL 查询包装在 XQuery 语句中:这种方法使用 SPARQL 来确定整个结果集,然后利用 XQuery 中的自定义排序规则来处理排序。分页也在 XQuery 中处理(很明显,在排序之前分页会破坏两者)。

第二个解决方案似乎对我们有用,但在我们认真考虑实施它之前,我需要查看性能成本。顺便说一句,我觉得很奇怪,SPARQL 的排序不支持排序规则,而它所基于的 XQuery 函数却支持排序规则。假设其用户永远不想使用基本 Unicode 代码点排序之外的任何其他方式对未标记的文字值进行排序似乎是不合逻辑的。在什么时候我可以合理地采用基于 XQuery 构建的东西并将其嵌入到 XQuery 中,因为创建者似乎“遗漏了一些东西?”