首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单FLWOR中的函数和子选择

单FLWOR中的函数和子选择
EN

Stack Overflow用户
提问于 2013-05-02 12:02:13
回答 1查看 518关注 0票数 0

我正在编写一个XQuery来分析大量存储查询的XML文件,类似于下面的示例。对于这些查询,我想计算各种子元素的平均值、和以及其他信息。此外,我还想在同一个文档中生成查询的子部分,例如,所有没有命中的查询。

由于我将处理数十万个XML文件,所以我希望使我的xquery尽可能高效。我尝试过跨文档使用单一的for迭代,但我根本不知道如何获得所需的所有信息。

下面是一个示例XML:

代码语言:javascript
复制
<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&#x9;" />
      <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>

这里是XQuery:

代码语言:javascript
复制
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}"/>

它正确地返回包含10个XML文件的示例的<Statistics numQueries="10" avgHits="19.7"/>。这样做对吗?我似乎需要double for,这样我就可以将来自不相交文件的查询分组在一起,因为否则我似乎无法在它们上运行函数。

我还需要在创建的<Statistics>元素中重复一些查询。我需要重复一次FLWOR声明吗?我不能在计算它们的for语句之外带来求和值或平均值,但我不能计算它们并执行子选择,因为我必须包括一个筛选它们的位置。

(Update)这是我提出的包含查询子部分的查询,但正如我前面提到的,我很担心性能。

代码语言:javascript
复制
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>

XQuery处理器是会优化my语句,还是会通过它们访问所有的for循环?第一个let语句会阻止这种情况吗?

这就是我想要生成的那种文档:

代码语言:javascript
复制
<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>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-25 05:56:33

如果您担心性能问题,您应该使用XML数据库(如果您还没有这样做),因为它将通过索引数据来提高性能。此外,使用`db:open("your-db")并将您的BaseX文件加载到数据库中,您可以使用BaseX访问所有节点,避免嵌套的for循环。此外,您可以使用一些特定于数据库的索引,这将加快您的查询。如果您有一个简单的XQuery导入器处理fs,那么它肯定会触及每个xml文件,因为它对每个文件中的数据一无所知。除此之外,你的XQuery在我看来基本上没问题。正如我试图指出的那样,优化在很大程度上取决于您正在使用的处理器/数据库。 是的,您将不得不运行一些测试,几乎不可能说任何关于实时运行时的内容,因为它在很大程度上取决于您的数据和查询。但是,稍后转到数据库应该不会太难,所以我不会太担心它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16337589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档