为组和计数优化两步 xquery
optimizing two-step xquery for group and count
在我的数据库(Xquery 3.1,eXist-db 4.7)中,我有 12,000 多个 TEI XML 文档(examples
),每个文档都可以有多个对单个独立 TEI 的引用keywords
.
的文档
这 12,000 个 example
文档中的每一个都如下所示,具有可变数量的 keyword
参考文献:
<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>
keyword
文档包含 2000 多个 xml:id
参考文献,每个参考文献包含 5 种语言翻译:
<category xml:id="KW0001">
<desc xml:lang="de">geliebter</desc>
<desc xml:lang="en">lover</desc>
<desc xml:lang="es">amante</desc>
<desc xml:lang="fr">amant</desc>
<desc xml:lang="it">amante</desc>
</category>
<category xml:id="KW0002">
<desc xml:lang="de">bischof</desc>
<desc xml:lang="en">bishop</desc>
<desc xml:lang="es">obispo</desc>
<desc xml:lang="fr">évêque</desc>
<desc xml:lang="it">vescovo</desc>
</category>
我查询的objective是获取examples
的选择(@group
)中的所有keywords
,然后将它们分组并统计为[=38] =].
我目前的解决方案需要很长时间,尽管已经为所有元素和属性建立了索引。我怀疑有更有效的方法将它们放在一起,但我看不到它。
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 文档是否可以引用关键字文档中没有的关键字,我上面显示的代码没有进行检查。
在我的数据库(Xquery 3.1,eXist-db 4.7)中,我有 12,000 多个 TEI XML 文档(examples
),每个文档都可以有多个对单个独立 TEI 的引用keywords
.
这 12,000 个 example
文档中的每一个都如下所示,具有可变数量的 keyword
参考文献:
<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>
keyword
文档包含 2000 多个 xml:id
参考文献,每个参考文献包含 5 种语言翻译:
<category xml:id="KW0001">
<desc xml:lang="de">geliebter</desc>
<desc xml:lang="en">lover</desc>
<desc xml:lang="es">amante</desc>
<desc xml:lang="fr">amant</desc>
<desc xml:lang="it">amante</desc>
</category>
<category xml:id="KW0002">
<desc xml:lang="de">bischof</desc>
<desc xml:lang="en">bishop</desc>
<desc xml:lang="es">obispo</desc>
<desc xml:lang="fr">évêque</desc>
<desc xml:lang="it">vescovo</desc>
</category>
我查询的objective是获取examples
的选择(@group
)中的所有keywords
,然后将它们分组并统计为[=38] =].
我目前的解决方案需要很长时间,尽管已经为所有元素和属性建立了索引。我怀疑有更有效的方法将它们放在一起,但我看不到它。
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 文档是否可以引用关键字文档中没有的关键字,我上面显示的代码没有进行检查。