No easy suggestions, but I have a couple.
If this is a common query and needs to be very efficient, then I would create a
node that represents the fact that elem/@attr1 eq elem/@attr2. Then you could
use something like:
cts:element-attribute-value-query(xs:QName('elem'),
xs:QName('attrs-equal'), '1').
If you prefer fewer XML changes and more database round-trips, you could put a
range index on elem/@attr1 (or elem/@attr2, but let's use attr1 for now). Then
you could write:
cts:element-attribute-value-query(
xs:QName('elem'), xs:QName('attr2'),
cts:element-attribute-values(
xs:QName('elem'), xs:QName('attr1')))
You could speed that query up even further by configuring a range index on both
element-attribute pairs, and then using cts:element-attribute-range-query with
'=' instead of cts:element-attribute-value-query. But the 'attrs-equal'
approach will still outperform it most of the time, and won't use as much
memory or disk space.
Why is any of this necessary? Because the cts:query constructors are designed
to be searchable - that is, to allow efficient index lookups. But there is no
index that would answer your question directly. There is an index entry for
every value of //elem/@attr1[. eq VALUE] and for //elem/@attr2[. eq VALUE] but
no index entry that says //elem/@attr1[. eq attr2]. So the most straightforward
way to resolve the XPath is to retrieve every match for //elem[@attr1][@attr2]
and then filter in memory to check the @attr1 eq @attr2 portion.
When xdmp:plan says "Path is fully searchable", I think it's only talking about
any node-name and node-type step(s), not any predicates. When I call it on your
XPath expression, it shows only one constraint, and I get exactly the same plan
if I simply drop the predicate. So I think it's really only searching on
//elem, and ignoring both attributes until the filtering phase (that's with
5.0-2).
Compare these plans:
xdmp:plan(//elem[@att1 = @att2]),
xdmp:plan(//elem),
xdmp:plan(//elem[@attr1])
=>
<qry:query-plan xmlns:qry="http://marklogic.com/cts/query">
<qry:info-trace>xdmp:eval("xdmp:plan(//elem[@att1 =
@att2]),&#13;&#10;xdmp:plan(//elem),&#1...", (), <options
xmlns="xdmp:eval"><database>18400529833056734238</database><root>/Users/mblakele/S...</options>)</qry:info-trace>
<qry:info-trace>Analyzing path: fn:collection()/descendant::elem[@att1 =
@att2]</qry:info-trace>
<qry:info-trace>Step 1 is searchable: fn:collection()</qry:info-trace>
<qry:info-trace>Step 2 is searchable: descendant::elem[@att1 =
@att2]</qry:info-trace>
<qry:info-trace>Path is fully searchable.</qry:info-trace>
<qry:info-trace>Gathering constraints.</qry:info-trace>
<qry:info-trace>Executing search.</qry:info-trace>
<qry:final-plan>
<qry:and-query>
<qry:term-query weight="0">
<qry:key>7128167059298760147</qry:key>
</qry:term-query>
</qry:and-query>
</qry:final-plan>
<qry:info-trace>Selected 0 fragments</qry:info-trace>
<qry:result estimate="0"/>
</qry:query-plan>
<qry:query-plan xmlns:qry="http://marklogic.com/cts/query">
<qry:info-trace>xdmp:eval("xdmp:plan(//elem[@att1 =
@att2]),&#13;&#10;xdmp:plan(//elem),&#1...", (), <options
xmlns="xdmp:eval"><database>18400529833056734238</database><root>/Users/mblakele/S...</options>)</qry:info-trace>
<qry:info-trace>Analyzing path:
fn:collection()/descendant::elem</qry:info-trace>
<qry:info-trace>Step 1 is searchable: fn:collection()</qry:info-trace>
<qry:info-trace>Step 2 is searchable: descendant::elem</qry:info-trace>
<qry:info-trace>Path is fully searchable.</qry:info-trace>
<qry:info-trace>Gathering constraints.</qry:info-trace>
<qry:info-trace>Executing search.</qry:info-trace>
<qry:final-plan>
<qry:and-query>
<qry:term-query weight="0">
<qry:key>7128167059298760147</qry:key>
</qry:term-query>
</qry:and-query>
</qry:final-plan>
<qry:info-trace>Selected 0 fragments</qry:info-trace>
<qry:result estimate="0"/>
</qry:query-plan>
<qry:query-plan xmlns:qry="http://marklogic.com/cts/query">
<qry:info-trace>xdmp:eval("xdmp:plan(//elem[@att1 =
@att2]),&#13;&#10;xdmp:plan(//elem),&#1...", (), <options
xmlns="xdmp:eval"><database>18400529833056734238</database><root>/Users/mblakele/S...</options>)</qry:info-trace>
<qry:info-trace>Analyzing path:
fn:collection()/descendant::elem[@attr1]</qry:info-trace>
<qry:info-trace>Step 1 is searchable: fn:collection()</qry:info-trace>
<qry:info-trace>Step 2 is searchable:
descendant::elem[@attr1]</qry:info-trace>
<qry:info-trace>Path is fully searchable.</qry:info-trace>
<qry:info-trace>Gathering constraints.</qry:info-trace>
<qry:info-trace>Step 2 predicate 1 contributed 1 constraint:
@attr1</qry:info-trace>
<qry:partial-plan>
<qry:term-query weight="0">
<qry:key>11100480210632785569</qry:key>
</qry:term-query>
</qry:partial-plan>
<qry:info-trace>Step 2 predicate 1 contributed 1 constraint:
@attr1</qry:info-trace>
<qry:partial-plan>
<qry:term-query weight="0">
<qry:key>11100480210632785569</qry:key>
</qry:term-query>
</qry:partial-plan>
<qry:info-trace>Executing search.</qry:info-trace>
<qry:final-plan>
<qry:and-query>
<qry:or-query>
<qry:element-query>
<qry:key>7128167059298760147</qry:key>
<qry:and-query>
<qry:term-query weight="0">
<qry:key>11100480210632785569</qry:key>
</qry:term-query>
</qry:and-query>
</qry:element-query>
<qry:and-query>
<qry:term-query weight="0">
<qry:key>11397336598217694489</qry:key>
</qry:term-query>
<qry:term-query weight="0">
<qry:key>7128167059298760147</qry:key>
</qry:term-query>
<qry:term-query weight="0">
<qry:key>11100480210632785569</qry:key>
</qry:term-query>
</qry:and-query>
</qry:or-query>
</qry:and-query>
</qry:final-plan>
<qry:info-trace>Selected 0 fragments</qry:info-trace>
<qry:result estimate="0"/>
</qry:query-plan>
If attr1 or attr2 aren't ubiquitous, then I think the efficient way to write
the XPath might be this odd-looking expression:
//elem[@attr1][@attr2][@att1 = @att2]
-- Mike
On 12 Feb 2012, at 01:16 , Geert Josten wrote:
> I am trying to isolate some specific element with two attributes who's
> values are equal. I know I can use an expression like doc()//elem[@att1 =
> @att2], which is even fully searchable according to xdmp:plan, but I'd
> prefer a cts:query, which I could pass into cts:element-attribute-values.
> I need unique values, and I am trying to prevent using distinct-values on
> the above XPath expression..
>
> Any suggestions?
>
> Kind regards,
> Geert
>
> drs. G.P.H. (Geert) Josten
> Senior Developer
>
>
>
> Dayon B.V.
> Delftechpark 37b
> 2628 XJ Delft
>
> T +31 (0)88 26 82 570
>
> [email protected]
> www.dayon.nl
>
> De informatie - verzonden in of met dit e-mailbericht - is afkomstig van
> Dayon BV en is uitsluitend bestemd voor de geadresseerde. Indien u dit
> bericht onbedoeld hebt ontvangen, verzoeken wij u het te verwijderen. Aan
> dit bericht kunnen geen rechten worden ontleend.
> _______________________________________________
> General mailing list
> [email protected]
> http://developer.marklogic.com/mailman/listinfo/general
>
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general