问题描述
我正在使用XQuery / BaseX浏览大型XML文件以查找某些计数器的历史数据。将所有文件压缩并存储在驱动器上的某个位置。文件的重要部分如下所示:
<measInfo xmlns="http://www.hehe.org/foo/" measInfoId="uplink speed">
<granPeriod duration="DS222S" endTime="2020-09-03T08:15:00+02:00"/>
<repPeriod duration="DS222S"/>
<measTypes>AFD123 AFD124 AFD125 AFD156</measTypes>
<measValue measObjLdn="PLDS-PLDS/STBHG-532632">
<measResults>23 42 12 43</measResults>
</measValue>
</measInfo>
我建立了以下查询:
declare default element namespace "http://www.hehe.org/foo/";
let $sought := ["AFD124","AFD125"]
let $datasource := collection("C:\Users\Patryk\Desktop\folderwitharchives")
let $filename := concat(convert:dateTime-to-integer(current-dateTime()),".xml")
for $meas in $datasource/measCollecFile/measData/measInfo return
for $measType at $i in $meas/tokenize(measTypes)[. = $sought] return
file:append($filename,<meas
measInfoId="{data($meas/@measInfoId)}"
measObjLdn="{data($meas/measValue/@measObjLdn)}"
>
{$meas/granPeriod}
{$meas/repPeriod}
<measType>{$measType}</measType>
<measValue>{$meas/measValue/tokenize(measResults," ")[$i]}</measValue>
</meas>)
该脚本有效,但是某些计数器(measType)需要花费大量时间。我阅读了有关索引的文档,我的想法是以某种方式对所有measTypes(字符串的一部分)建立索引,以便一旦我需要遍历整个存档以寻找计数器时,便可以快速访问它。我不确定直接对档案进行操作时是否可行?我需要为它们创建一个新的数据库吗?由于文件的大小,我不希望这样做。如何为这种情况创建索引?
解决方法
这不是我的问题的答案,但是我注意到,当我将XML节点写入文件时,执行时间要长得多。将任何其他字符串附加到文件中要快得多:
concat($measInfo/@measInfoId,",$measInfo/measValue/@measObjLdn,$measInfo/granPeriod,$measInfo/repPeriod,$measType,$tokenizedValues[$i]," "))
为什么?如何加快将XML节点写入文件的速度?
此外,我已经注意到将值附加到for循环内的文件中的时间更长,并且我怀疑这是因为在每次迭代中都必须再次打开该文件。有没有办法在整个查询中保持文件打开?