Xml 单个FLWOR中的函数和子选择
我正在编写一个XQuery来分析大量存储查询的XML文件,类似于下面的示例。对于这些查询,我想计算各种子元素的平均值、总和和其他信息。此外,我希望在同一文档中生成查询的子部分,例如,所有没有命中的查询 由于我将处理数十万个XML文件,我希望尽可能提高xquery的效率。我曾尝试在文档中使用一个Xml 单个FLWOR中的函数和子选择,xml,performance,xquery,Xml,Performance,Xquery,我正在编写一个XQuery来分析大量存储查询的XML文件,类似于下面的示例。对于这些查询,我想计算各种子元素的平均值、总和和其他信息。此外,我希望在同一文档中生成查询的子部分,例如,所有没有命中的查询 由于我将处理数十万个XML文件,我希望尽可能提高xquery的效率。我曾尝试在文档中使用一个来进行迭代,但我根本不知道如何获得所需的所有信息 下面是一个示例XML: <Query> <QueryString>Gigabyte Sapphire GTX-860</Q
来进行迭代,但我根本不知道如何获得所需的所有信息
下面是一个示例XML:
<Query>
<QueryString>Gigabyte Sapphire GTX-860</QueryString>
<StatusCode>0</StatusCode>
<QueryTime>0.04669069110297385</QueryTime>
<Hits>8</Hits>
<Date>2013-05-02</Date>
<Time>12:07:07</Time>
<LastModified>12:07:07</LastModified>
<Pages resultsPerPage="10" clickCount="2">
<Page resultCount="8" visited="true">
<Result index="1" clickIndex="0" timeViewed="0" pid="85405" title="DDR3 1024 MB" />
<Result index="2" clickIndex="1" timeViewed="178" pid="54065" title="ATK Excellium	" />
<Result index="3" clickIndex="0" timeViewed="0" pid="74902" title="Intel E9650" />
<Result index="4" clickIndex="0" timeViewed="0" pid="56468" title="ASUS Radeon HD 7980" />
<Result index="5" clickIndex="0" timeViewed="0" pid="31072" title="Intel E7500" />
<Result index="6" clickIndex="0" timeViewed="0" pid="26620" title="DDR3 2048 MB" />
<Result index="7" clickIndex="2" timeViewed="92" pid="55625" title="Gigabyte Sapphire 7770" />
<Result index="8" clickIndex="0" timeViewed="0" pid="67701" title="Intel E9650" />
</Page>
</Pages>
</Query>
如果您担心性能,您应该使用XML数据库(如果您还没有这样做),因为它将通过索引数据来提高性能。此外,例如,使用BaseX并将XML文件加载到数据库中,您可以使用``db:open(“您的db”)``访问所有节点,从而避免嵌套的for循环。此外,您还可以使用一些特定于数据库的索引,这将加快查询速度。如果您有一个简单的XQuery处理器处理fs,它肯定会触及每个xml文件,因为它对每个文件中的数据一无所知
除此之外,您的XQuery在我看来基本上还不错。正如我试图指出的,优化在很大程度上取决于您使用的处理器/数据库
是的,您将不得不运行一些测试,几乎不可能对实时运行时说任何事情,因为它严重依赖于您拥有的数据和查询。不过,以后切换到数据库应该不会太难,所以我不会太担心
你用的是什么处理器?如果您担心性能,您应该使用XML数据库(如果您还没有这样做),因为它将通过索引数据来提高性能。此外,例如,使用BaseX并将XML文件加载到数据库中,您可以使用``db:open(“您的db”)``访问所有节点,从而避免嵌套的for循环。此外,您还可以使用一些特定于数据库的索引,这将加快查询速度。如果您有一个简单的XQuery处理程序处理fs,它肯定会处理每个xml文件,因为它对每个文件中的数据一无所知。正如我试图指出的,优化在很大程度上取决于您使用的处理器/数据库。谢谢您的建议。我似乎陷入了一种循环逻辑,因为我们将使用的技术取决于我们获得的性能。例如,当文件仅仅存储在文件系统中时,除非性能太差,否则不会考虑使用XML数据库。转换将通过ApacheCamel进行,这可能意味着Saxon。我刚刚通过EditiX Saxon处理器运行了上述查询,似乎不到一分钟就可以解析10万个文档。我必须看看额外的for构造是否会影响运行时。是的,您必须运行一些测试,几乎不可能对实时运行时做任何说明,因为它在很大程度上取决于您拥有的数据和查询。不过,以后切换到数据库应该不会太难,所以我不会太担心。@dirkk谢谢你的建议。如果你能把你关于测试脚本和基于结果性能的缩放技术的建议变成一个答案,我可以接受。
let $doc := collection('file:///C:/REP/XML/input?select=*.xml')
for $y in (
<Queries>
{
for $x in $doc
let $hits := $x/Query/Hits
return <Query hits="{$hits}" >{$x/Query/QueryString/string()}</Query>
}
</Queries>
)
let $avgHits := avg(data($y/Query/@hits))
let $numQueries := count($y/*)
return <Statistics avgHits="{$avgHits}" numQueries="{$numQueries}"/>
let $doc := collection('file:///C:/REP/XML/input?select=*.xml')
for $y in (
<Queries>
{
for $x in $doc
let $hits := $x/Query/Hits
return <Query hits="{$hits}" >{$x/Query/QueryString/string()}</Query>
}
</Queries>
)
let $avgHits := avg(data($y/Query/@hits))
let $numQueries := count($y/*)
return <Statistics avgHits="{$avgHits}" numQueries="{$numQueries}">
{
for $x in $doc
let $hits := $x/Query/Hits
where $x/Query/Hits < 10
return <Query hits="{$hits}" >{$x/Query/QueryString/string()}</Query>
}
</Statistics>
<DailyStats date="2013-04-15" >
<DayStats>
<QueryCount>24644</QueryCount>
<Errors>0</Errors>
<EmptySearches>643</EmptySearches>
<AverageSearchTime>0.0213</AverageSearchTime>
<AverageSearchesPerHour>236</AverageSearchesPerHour>
</DayStats>
<StoredQueries>
<FailedSearches>
<FailedSearch time="23:33:34" query="blurey" searchTime="0.0524" />
</FailedSearches>
</StoredQueries>
</DailyStats>