XQuery-优化效率低下的查询策略(在eXist-db中)

时间:2018-11-01 19:04:21

标签: xpath xquery exist-db

环境:eXist-DB 4.4 / Xquery 3.1

我有数百个tei:xml文档,其中编码了名为实体persNameplaceName的实体。文件在

 collection("db/fooapp/data")

persNameplaceName的每个实例都有一个属性@nymRef,该属性包含一个引用主文档中的xml:id的值:

 db/fooapp/data/codes_persons.xml

 db/fooapp/data/codes_places.xml

这些主文档除其他外,还包含每个人或每个地方的规范名称。

例如,我经常对某个单一名称进行单一查询

let $x := some @nymRef

let $y := doc(db/fooapp/data/codes_places.xml)//tei:place[@xml:id=$x]//tei:placeName/text()

return $y

但是,有时候我需要这样做,遍历庞大的列表。例如,在所有文档中,我需要为id输出一个seg,并且它有一个(或多个)子元素placeName/@nymRef

 <seg xml:id="fooref">some text<placeName nymRef="fooplace"/>some text</seg>

任务是获取所有seg/@xml:id,然后查找并在其下面输出任何placeName/@nymRef的规范名称。这会导致大量往返过程确实效率低下,但是我不知道在eXist-DB中执行此操作的任何其他方法。昂贵的往返行程以let $c表示,并在return之间循环:

let $coll := collection("db/fooapp/data")

for $a in $coll//seg

    for $b in $a//placeName

        let $c := $doc("db/fooapp/data/codes_places.xml")//tei:place[@xml:id=$b/data(@nymRef)]//tei:placeName/text()

        return 
              <tr>
                <td>{$a/@xml:id}</td>
                <td>{$c}</td>
              </tr>

单个表输出最多可以增加数百次往返行程。

我不反对在必要时将任务重组为多个功能。

非常感谢。

1 个答案:

答案 0 :(得分:1)

请向我们提供输入xml和所需的输出,否则无法重写您的查询。我们还需要查看您的索引配置。

关于避免往返的一些一般建议:

  • 首先,请参阅我的previous answer,以回答关于使用 ft:query()。当做[@xml:id=$b/data(@nymRef)]存在时,使用 索引还是您强迫它不进行字符串比较 在该字符串上配置了索引?

  • id()是查找xml:id值的最快方法

  • distinct-values是您的朋友,只能查找每个 键:值对一次。

  • 使用单个for循环来避免对同一数据进行多次迭代 次。

  • 尽可能使用限制性更强的XPath表达式,// 可能会将大量不必要的数据加载到内存中。

所有这些以及更多内容都可以在documentation

中找到