使用xquery和FLWOR在BaseX中迭代大型XML文档的最有效方法

使用xquery和FLWOR在BaseX中迭代大型XML文档的最有效方法,xquery,basex,flwor,Xquery,Basex,Flwor,我面临着一个有趣的问题,我需要遍历多个大XML文件(每个文件都有数百MB),并从每个元素输出特定的数据,并尽可能快地完成。 示例: Points.xml: <points> <point> <identifier>bb25c66c-27d0-447f-aaad-bd8290b332fd</identifier> <name>A</name> </point> <point>

我面临着一个有趣的问题,我需要遍历多个大XML文件(每个文件都有数百MB),并从每个元素输出特定的数据,并尽可能快地完成。 示例:

Points.xml:

<points>
  <point>
    <identifier>bb25c66c-27d0-447f-aaad-bd8290b332fd</identifier>
    <name>A</name>
  </point>
  <point>
    <identifier>f187cc74-2709-4464-995c-b3bdcae46b39</identifier>
    <name>B</name>
  </point>
</points>
我不能修改文档本身,这是我必须处理的,现在的问题是-如何基于标识符尽可能高效地链接元素?我说的是实现这一点的方法,也许是思考这一点的另一种方式,而不是实际的代码,因为它最终将是完全不同的

我已尝试在路线上循环,然后使用FLWOR查找点:

for $route in doc('routes.xml')/routes/route
  return concat(
    $route/name/text(),
    ' - ',
    doc('points.xml')/points/point[./identifier/text() = substring-after($route/pointLink/@xlink:href, 'urn:uuid:')]/name/text()
  )
结果不是很好(花了将近一个小时才完成)。这种方法也有类似的情况:

for $route in doc('routes.xml')/routes/route,
    $point in doc('points.xml')/points/point[./identifier/text() = substring-after($route/pointLink/@xlink:href, 'urn:uuid:')]
  return concat(
    $route/name/text(),
    ' - ',
    $point/name/text()
  )
最后,我需要在输出中使用来自点/路线的更多子元素,因此我认为我必须使用for迭代它们,然后在输出中使用concat,但可能我错了,这就是我在这里提问的原因


是否有什么我忽略了,或者根本没有更快的方法做到这一点?

正如Martin Honnen在评论中所说,问题确实是索引。
简单地创建一个属性索引(createindex属性)有助于将查询时间从大约45分钟减少到不到一秒钟。难以置信。

当您使用BaseX时,是否已将文档插入到数据库中以使用文本索引之类的索引?这样,任何用于比较
点/标识符
的交叉引用都应该运行得更快。文档确实在数据库中,但我一直使用通过doc直接访问它们,因为在我已经解决的类似情况下,它被证明快了好几倍(BaseX将doc优化为db:open-pre)。我还在实际查询中使用精确路径,而不是//或*,因此这也不会有问题。然而,从你发布的链接中,我在信息面板的任何地方都看不到“为..应用文本索引”,所以我将尝试深入探讨,谢谢!
for $route in doc('routes.xml')/routes/route
  return concat(
    $route/name/text(),
    ' - ',
    doc('points.xml')/points/point[./identifier/text() = substring-after($route/pointLink/@xlink:href, 'urn:uuid:')]/name/text()
  )
for $route in doc('routes.xml')/routes/route,
    $point in doc('points.xml')/points/point[./identifier/text() = substring-after($route/pointLink/@xlink:href, 'urn:uuid:')]
  return concat(
    $route/name/text(),
    ' - ',
    $point/name/text()
  )