XQuery—优化低效查询策略(在eXistdb中)



环境: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

但是,有时我需要这样做,在巨大的列表中循环。例如,在所有文档中,我需要为seg输出一个id,并且它有一个(或多个(子元素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>

对于单个表输出,这可能会导致数百次往返。

如有必要,我不反对将这项任务改组为多项职能。

非常感谢。

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

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

  • 首先,请参阅我之前对您关于使用ft:query()。当执行[@xml:id=$b/data(@nymRef)]时,使用索引还是强制它进行字符串比较是否在该字符串上配置了索引?

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

  • distinct-values是你的朋友只查找每一个不同的key:值对一次。

  • 使用单个for循环以避免在同一数据上重复多次时间。

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

所有这些以及更多信息都可以在文档中找到

最新更新