BaseX - 在XQuery中使用封闭xml时内存不足

uni*_*orn 3 xquery basex

我一直在尝试查询包含超过1500000项的BaseX数据库.当我运行此查询

for $item in collection('coll')//item
    return $item (: returns an xml element :)
Run Code Online (Sandbox Code Playgroud)

它在不到一秒的时间内执行.

但是当我尝试在xml中返回结果时,我得到一个"Out of main memory"错误.

<xml>{
    for $item in collection('coll')//item
       return $item
}</xml>
Run Code Online (Sandbox Code Playgroud)

这是让我想放弃本机xml db方法的东西(与其他数据库一样,例如eXistDB),所以如果任何人有任何信息这个问题,那将是非常有帮助的.

谢谢

Chr*_*rün 5

由于XQuery的语义,如果所有子节点都被新的父节点包装,则需要复制它们.以下查询演示了这一点,该查询比较了原始节点和复制节点的节点标识.它会产生false:

let $node := <node/>
let $parent := <parent>{ $node }</parent>
return $parent/node is $node
Run Code Online (Sandbox Code Playgroud)

由于复制数百万个节点是昂贵的,这不可避免地导致内存不足的错误.

如果您将结果写入文件,这是一个实用的解决方案来解决这个限制:

(:~ 
 : Writes element to a file, wrapped by a root node.
 : @param  $path      path to file
 : @param  $elements  elements to write
 : @param  $name      name of root node
 :)
declare function local:write-to(
  $path      as xs:string,
  $elements  as element()*,
  $name      as xs:string
) as empty-sequence() {
  file:write-text($path, '<' || $name || '>'),
  file:append($path, $elements),
  file:append-text($path, '</' || $name || '>')
};

local:write-to('result.xml', <result/>, 'root')
Run Code Online (Sandbox Code Playgroud)

预测批评:这是一个明确的黑客.例如,该方法与BaseX的各种非默认序列化参数冲突(如果需要输出XML声明,结果将不会很好地形成等).