This is the best I could come up with:

let $qnames := for $i in ("chapter","subchapter","section") return xs:QName($i)
return cts:search(//(chapter|subchapter|section),
            cts:and-query((
                cts:directory-query($coll,"infinity"),
                cts:element-attribute-value-query($qnames, 
xs:QName("enum"),$enum))))[@enum eq $enum]

This is still about twice as fast as the xpath, even if I can't easily work 
around the predicate at the end.

What's interesting is that the value query is slightly faster than the element 
range query. I assume they're both using the range index, and the value query 
is just doing it in less steps. 

Thanks for your help.

-Will

-----Original Message-----
From: [email protected] 
[mailto:[email protected]] On Behalf Of Will Thompson
Sent: Wednesday, July 27, 2011 6:07 PM
To: General MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] xpath to cts query question

The data unfortunately won't allow for a more specific path. I was trying to do 
something along the lines of what Mike suggested to utilize an attribute range 
index, but the problem is that the cts:search will return multiple documents 
because it includes ancestors, while the Xpath does not. 

Here's a less vague example:

//(chapter|subchapter|section)[@enum="123"] will only return, say, the section 
that matches, 

but this:

cts:search(
  doc(),
  cts:element-attribute-range-query(
    (xs:QName("chapter"), xs:QName("subchapter"), xs:QName("section")),
    "=", 
    xs:QName("enum"), $enum)
  )
) 

will return the section and its ancestor chapter and subchapter, since they are 
included in the searchable expression. The only way I could think to work 
around this is separate queries, each with a searchable expression that 
corresponds to the range query.

-Will


-----Original Message-----
From: [email protected] 
[mailto:[email protected]] On Behalf Of Danny Sokolsky
Sent: Wednesday, July 27, 2011 5:51 PM
To: General MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] xpath to cts query question

Another thing that might help is if you know the full path to the nodes.  With 
//, it will have to look for the nodes anywhere in the documents.  

-Danny

-----Original Message-----
From: [email protected] 
[mailto:[email protected]] On Behalf Of Michael Blakeley
Sent: Wednesday, July 27, 2011 3:49 PM
To: General MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] xpath to cts query question

xdmp:plan help with that:

...
  <qry:info-trace>Analyzing path: 
fn:collection()/descendant-or-self::node()/(a|b|c|d|e|f|g)[@foo = 
"bar"]</qry:info-trace>
  <qry:info-trace>Step 1 is searchable: fn:collection()</qry:info-trace>
  <qry:info-trace>Step 2 does not use indexes: 
descendant-or-self::node()</qry:info-trace>
  <qry:info-trace>Step 3 is searchable: (a|b|c|d|e|f|g)[@foo = 
"bar"]</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 3 predicate 1 contributed 1 constraint: @foo = 
"bar"</qry:info-trace>
...

The cts:query would be something like:

xdmp:plan(
  cts:search(doc(),
    cts:element-attribute-value-query(
      for $i in ('a', 'b', 'c', 'd', 'e', 'f', 'g')
      return xs:QName($i),
      xs:QName('foo'), 'bar')))

If that isn't fast enough, the next step might be an element-attribute range 
index on every element-attribute combination, and switching to 
cts:element-range-query with operator '='.

-- Mike

On 27 Jul 2011, at 15:36 , Will Thompson wrote:

> Thanks Danny. What I'm mainly trying to do is speed up some slow xpath. I've 
> optimized a lot of this module, but this xpath seems to be one of the 
> remaining bottlenecks: //(a|b|c|d|e|f|g)[@foo = "bar"]. I thought that by 
> converting it to a cts:query it would be faster. Or is this Xpath already 
> going to be optimized by MLS?
> 
> -Will
> 
> -----Original Message-----
> From: [email protected] 
> [mailto:[email protected]] On Behalf Of Danny Sokolsky
> Sent: Wednesday, July 27, 2011 5:20 PM
> To: General MarkLogic Developer Discussion
> Subject: Re: [MarkLogic Dev General] xpath to cts query question
> 
> Hi Will,
> 
> I might not be understanding what you are doing here, but here are a few 
> ideas.
> 
> I think you can use that XPath in the first arg of cts:search, as long as you 
> do not put any variables in it.  Something like this:
> 
> cts:search(//(a|b|c|d|e|f|g)[@foo = "bar"], "hello")
> 
> Also, in cts:query, you can do a cts:element-query with the 
> cts:element-attribute-query as its second arg.  Something like:
> 
> cts:element-query((xs:QName("a"), xs:QName("b")), 
>  cts:element-attribute-word-query((xs:QName("a"), 
>      xs:QName("b")), xs:QName("foo"), "bar"))
> 
> -Danny
> 
> -----Original Message-----
> From: [email protected] 
> [mailto:[email protected]] On Behalf Of Will Thompson
> Sent: Wednesday, July 27, 2011 2:51 PM
> To: General MarkLogic Developer Discussion
> Subject: [MarkLogic Dev General] xpath to cts query question
> 
> I'm trying to create the cts equivalent of essentially this:
> 
> //(a|b|c|d|e|f|g)[@attr = $val]
> 
> But it seems like I would have join multiple cts:search()s, one for each 
> element, since I only want the matching element, and not its parent (so I 
> can't do something like cts:search(//(a|b|c|d|e|f|g), 
> cts:element-attribute-value-query((xs:QName("a"),...,(xs:QName("g")),xs:QName("attr"),$val)).
> 
> cts:search(//a, 
> cts:element-attribute-value-query(xs:QName("a"),xs:QName("attr"),$val))
> | cts:search(//b, 
> cts:element-attribute-value-query(xs:QName("b"),xs:QName("attr"),$val))
> | cts:search(//c, 
> cts:element-attribute-value-query(xs:QName("c"),xs:QName("attr"),$val))
> ...
> | cts:search(//g, 
> cts:element-attribute-value-query(xs:QName("g"),xs:QName("attr"),$val))
> 
> Is there a better way to do this?
> 
> Thank you!
> 
> -Will
> _______________________________________________
> General mailing list
> [email protected]
> http://developer.marklogic.com/mailman/listinfo/general
> _______________________________________________
> General mailing list
> [email protected]
> http://developer.marklogic.com/mailman/listinfo/general
> _______________________________________________
> General mailing list
> [email protected]
> http://developer.marklogic.com/mailman/listinfo/general
> 

_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general

Reply via email to