我的 xpath 查询无法使用范围索引。我究竟做错了什么?
My xpath query fails to use the range index. What am I doing wrong?
我通过它的 id 找到一个相关元素,存储在引用元素的 href 中,如下所示:
let $item := ($doc//(map|question|theory|reading|glossgroup))[@id = $ref/@href]
阅读 ExistDB 的文档,我很确定一个简单的 <create qname="@ID" type="xs:string" />
索引就足够了,甚至应该是自动生成的。但是查看分析器,我的查询没有使用任何索引。
我什至试过了
let $item := $doc//map[@id = $ref/@href]
并像这样用 id 字段创建了一个索引
<index>
<range>
<create qname="map" type="xs:string">
<field name="map-id" match="@id" type="xs:string" />
</create>
</range>
</index>
但似乎没有任何效果。
我是 ExistDB 的新手.. 可能做了一些明显的错误,所以如果有人能指出我正确的方向:)?
示例XML:
<root>
<map id="ide931fee3-6a45-4435-a8d2-f018ae2ca2ea">
<mapref href="f80cc8c8-6b6d-4005-b2e9-85eac2ee2fbf.1.36" />
</map>
<map id="f80cc8c8-6b6d-4005-b2e9-85eac2ee2fbf.1.36">
<topicref href="47aed1dd-62f7-4fb6-ae76-dbfcde0a4bab.1.9" />
</map>
<question id="47aed1dd-62f7-4fb6-ae76-dbfcde0a4bab.1.9">
...
</question>
</root>
如果可以,我建议切换到 xml:id 属性。这是由 exist-db 自动索引的。然后您可以删除索引定义并使用 id()
函数检索元素。
示例
$doc/id($ref/@href)
Use fn:id to lookup xml:id attributes
eXist-db automatically indexes all xml:id attributes and other
attributes with type ID as declared in a DTD (if validation is
enabled). This automatic index is used by the standard id functions
and provides a fast way to look up an element. For example,
id("sect1")/head
works through a fast index lookup.
However, the equivalent expression //section[@xml:id = 'sect1']/head
will not use the id index.
Some users have reported that larger xml:id values have a negative performance impact.
如果你还想坚持@id
:
创建范围索引:
<index>
<range>
<create match="@id" type="xs:string" />
</range>
</index>
这应该会告诉您基本的索引用法。
重写您的查询可能会进一步提高性能(完全优化):
$doc//(map|question|theory|reading|glossgroup)/@id[. = $ref/@href]/..
对于任何对我最终选择的解决方案感兴趣的人。不幸的是,列出的答案并没有真正使我的查询更快,也没有让我知道如何重写它。
所以我这样做了:
let $item := $doc//map[@id = $ref/@href]
let $item := if ($item) then $item else $doc//question[@id = $ref/@href]
let $item := if ($item) then $item else $doc//theory[@id = $ref/@href]
let $item := if ($item) then $item else $doc//reading[@id = $ref/@href]
let $item := if ($item) then $item else $doc//glossgroup[@id = $ref/@href]
并分别创建了相应的索引
<create qname="map" type="xs:string">
<field name="map-id" match="@id" type="xs:string" />
</create>
<create qname="question" type="xs:string">
<field name="question-id" match="@id" type="xs:string" />
</create>
<create qname="theory" type="xs:string">
<field name="theory-id" match="@id" type="xs:string" />
</create>
<create qname="reading" type="xs:string">
<field name="reading-id" match="@id" type="xs:string" />
</create>
<create qname="glossgroup" type="xs:string">
<field name="glossgroup-id" match="@id" type="xs:string" />
</create>
我通过它的 id 找到一个相关元素,存储在引用元素的 href 中,如下所示:
let $item := ($doc//(map|question|theory|reading|glossgroup))[@id = $ref/@href]
阅读 ExistDB 的文档,我很确定一个简单的 <create qname="@ID" type="xs:string" />
索引就足够了,甚至应该是自动生成的。但是查看分析器,我的查询没有使用任何索引。
我什至试过了
let $item := $doc//map[@id = $ref/@href]
并像这样用 id 字段创建了一个索引
<index>
<range>
<create qname="map" type="xs:string">
<field name="map-id" match="@id" type="xs:string" />
</create>
</range>
</index>
但似乎没有任何效果。
我是 ExistDB 的新手.. 可能做了一些明显的错误,所以如果有人能指出我正确的方向:)?
示例XML:
<root>
<map id="ide931fee3-6a45-4435-a8d2-f018ae2ca2ea">
<mapref href="f80cc8c8-6b6d-4005-b2e9-85eac2ee2fbf.1.36" />
</map>
<map id="f80cc8c8-6b6d-4005-b2e9-85eac2ee2fbf.1.36">
<topicref href="47aed1dd-62f7-4fb6-ae76-dbfcde0a4bab.1.9" />
</map>
<question id="47aed1dd-62f7-4fb6-ae76-dbfcde0a4bab.1.9">
...
</question>
</root>
如果可以,我建议切换到 xml:id 属性。这是由 exist-db 自动索引的。然后您可以删除索引定义并使用 id()
函数检索元素。
示例
$doc/id($ref/@href)
Use fn:id to lookup xml:id attributes
eXist-db automatically indexes all xml:id attributes and other attributes with type ID as declared in a DTD (if validation is enabled). This automatic index is used by the standard id functions and provides a fast way to look up an element. For example,
id("sect1")/head
works through a fast index lookup.However, the equivalent expression
//section[@xml:id = 'sect1']/head
will not use the id index.Some users have reported that larger xml:id values have a negative performance impact.
如果你还想坚持@id
:
创建范围索引:
<index>
<range>
<create match="@id" type="xs:string" />
</range>
</index>
这应该会告诉您基本的索引用法。
重写您的查询可能会进一步提高性能(完全优化):
$doc//(map|question|theory|reading|glossgroup)/@id[. = $ref/@href]/..
对于任何对我最终选择的解决方案感兴趣的人。不幸的是,列出的答案并没有真正使我的查询更快,也没有让我知道如何重写它。
所以我这样做了:
let $item := $doc//map[@id = $ref/@href]
let $item := if ($item) then $item else $doc//question[@id = $ref/@href]
let $item := if ($item) then $item else $doc//theory[@id = $ref/@href]
let $item := if ($item) then $item else $doc//reading[@id = $ref/@href]
let $item := if ($item) then $item else $doc//glossgroup[@id = $ref/@href]
并分别创建了相应的索引
<create qname="map" type="xs:string">
<field name="map-id" match="@id" type="xs:string" />
</create>
<create qname="question" type="xs:string">
<field name="question-id" match="@id" type="xs:string" />
</create>
<create qname="theory" type="xs:string">
<field name="theory-id" match="@id" type="xs:string" />
</create>
<create qname="reading" type="xs:string">
<field name="reading-id" match="@id" type="xs:string" />
</create>
<create qname="glossgroup" type="xs:string">
<field name="glossgroup-id" match="@id" type="xs:string" />
</create>