eXist-db 集合排序

eXist-db collection sort

开始使用 pos

在 eXist 4.7 中,我在 myapp/data/ 中有一个集合,其中包含数千个 TEI XML 文档。我使用 Martin Honnen 的以下解决方案来获取某个文档之前和之后的文档

let $data := myapp/data
let $examples := $data/tei:TEI[@type="example"]
for $example at $pos in $examples
where $example/@xml:id = 'TC0005'
return (
    $examples[$pos - 1],
    $example
    $examples[$pos + 1]
    )

我希望 $examples[$pos - 1] 生成文档 'TC0004',$examples[$pos + 1] 生成 'TC0006'(基于 eXide 集合导航视图中看到的排序顺序)例子)。他们不这样做,而是产生相反的结果。

Honnen 和 Michael Kay 回应说

ordering of documents within a collection is very much processor-dependent

应用 order by $example/@xml:id ascending 子句并没有使结果变得更好。

所以,问题是我怎样才能对 $data 施加字母数字顺序?

非常感谢。

您似乎可以在 XQuery 级别将 let $examples := $data/tei:TEI[@type="example"] 更改为

let $examples := sort($data/tei:TEI[@type="example"], (), function($e) { $e/@xml:id })

(假设 XQuery/XPath 3.1 高阶 sort 函数可用)或

let $examples := for $e in $data/tei:TEI[@type="example"] order by $e/@xml:id return $e

使用 order by 子句。

我不知道 exist-db 是否有某种方法可以在创建或选择集合期间强加顺序。

根据旧版 eXist 的经验,经过循环时的 $pos 值不是排序后的位置顺序。是穿越时的位置。

您首先要做的是创建一个有序列表,然后从您要查找的列表中获取三个项目。

let $data := myapp/data[tei:TEI/@type eq 'example']
let $examples := for $e in $data order by $e/@xml:id ascending return $e
let $pos := index-of($examples/@xml:id, 'TC0005')
return if (count($pos) eq 1) then (
  if ($pos gt 1) then $examples[$pos - 1] else (),
  $examples[$pos]
  $examples[$pos + 1]
) else ()

这种方法的一个潜在问题是您每次都必须对所有项目进行排序。创建一个排序的缓存列表可以缓解这个问题,并且还可以实现更高效的查询,您可以在查询结果中使用 preceding-siblingfollowing-sibling

如果 ID 的命名约定一致,另一种可能的解决方案是查询前后 ID。

检查 $pos 中是否有一项是为了防止 @xml:id 不唯一的情况(是的,这违反规范,但它发生在现实世界的数据中) 或不存在任何项目。请记住,index-of returns 索引数组 - 0 或更多。