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