为组和计数优化两步xquery
在我的数据库Xquery 3.1、eXist db 4.7中,我有12000多个TEI XML文档示例,每个示例都可以对单个独立的关键字TEI文档进行多个引用 这12000个示例文档中的每一个都类似于下面的文档,具有不同数量的关键字引用:为组和计数优化两步xquery,xquery,exist-db,Xquery,Exist Db,在我的数据库Xquery 3.1、eXist db 4.7中,我有12000多个TEI XML文档示例,每个示例都可以对单个独立的关键字TEI文档进行多个引用 这12000个示例文档中的每一个都类似于下面的文档,具有不同数量的关键字引用: <TEI type="example" group="X"> <teiHeader>some content</teiHeader> <text> <front> <
<TEI type="example" group="X">
<teiHeader>some content</teiHeader>
<text>
<front>
<div type="keywords">
<list type="keywords">
<item type="keyword" corresp="KW0002"/>
<item type="keyword" corresp="KW0034"/>
<item type="keyword" corresp="KW0349"/>
<item type="keyword" corresp="KW0670"/>
<item type="keyword" corresp="KW1987"/>
</list>
</div>
</front>
</text>
</TEI>
我的查询的目的是获取selection@group示例中的所有关键字,然后对它们进行分组,并对它们进行HTML计数
我当前的解决方案需要很长时间,尽管已经为所有元素和属性编制了索引。我怀疑有一种更有效的方法来整合这些,但我看不出来
let $cols := collection($mydatabase)//TEI[@group="X"]
let $kwdoc := doc("keywords.xml")//category
let $kws := distinct-values($cols//item[@type="keyword"]/data(@corresp))
let $lis := for $kw in $kws
let $count := count($cols//item[@type="keyword" and @corresp=$kw])
order by $count descending
return
<li>
<a href="{concat("www.example.com/keywords/",$kw)}">
{for $x in $kwdoc[@xml:id=$kw]/tei:desc
return <span class="{@xml:lang}">{$x/text()}</span>}
({$count})
</a>
</li>
return <ul>{$lis}</ul>
这将生成如下所示的HTML项:
<ul>
<li>
<a href="www.example.com/keywords/KW0001">
<span class="de">geliebter</span>
<span class="en">lover</span>
<span class="es">amante</span>
<span class="fr">amant</span>
<span class="it">amante</span>
</a>
(64)
</li>
<li>
<a href="www.example.com/keywords/KW0002">
<span class="de">bischof</span>
<span class="en">bishop</span>
<span class="es">obispo</span>
<span class="fr">évêque</span>
<span class="it">vescovo</span>
</a>
(64)
</li>
</ul>
非常感谢。我认为在XQuery 3中,您应该使用group by进行分组,希望这也能表现得更好:
let $cols := collection($mydatabase)//TEI[@group="X"]
let $kwdoc := doc("keywords.xml")//category
let $lis :=
for $group in $cols//item[@type = "keyword"]
group by $keyword := $group/@corresp
order by count($group) descending
return
<li>
<a href="{concat("www.example.com/keywords/",$keyword )}">
{for $desc in id($keyword, $kwdoc)/desc
return <span class="{$desc/@xml:lang}">{$desc/text()}</span>}
({count($group)})
</a>
</li>
return <ul>{$lis}</ul>
我唯一没有完全理解的问题是$cols中的TEI文档是否可以引用关键字文档中没有的关键字,上面我显示的代码没有进行检查。我将测试这一点,并让您知道它是如何执行的。$cols中没有“孤立”关键字ID…非常好的结果:这将一个耗时6-7秒的查询变成了一个获取@jbrehr distinct值的查询,速度非常慢,如果可能的话,应该避免/替换为group by。您能对时间安排发表评论吗?很难知道多长时间就是多长时间-我将做一个比较:正如我在上面构建的那样,一个大型查询需要6-7秒;根据eXide的说法,Martin Honnen在下面的解决方案将相同的查询时间缩短到了不到1秒,约0.5秒。
let $cols := collection($mydatabase)//TEI[@group="X"]
let $kwdoc := doc("keywords.xml")//category
let $lis :=
for $group in $cols//item[@type = "keyword"]
group by $keyword := $group/@corresp
order by count($group) descending
return
<li>
<a href="{concat("www.example.com/keywords/",$keyword )}">
{for $desc in id($keyword, $kwdoc)/desc
return <span class="{$desc/@xml:lang}">{$desc/text()}</span>}
({count($group)})
</a>
</li>
return <ul>{$lis}</ul>