Dear Michael,
Thank you very much for your reply, which gives me something to work
with. It would be a generally good thing for MarkLogic Server to have a
fast (index-based?) built-in id() function though. Wanting to retrieve
an element based on its ID is a fairly common use case.
Best,
Tim Finney
UVa Press
On Wed, 2009-07-22 at 09:07 -0700, Michael Blakeley wrote:
> Tim,
>
> You should be able to use the indexes if you can enumerate the parent
> element names. Let's start with some test docs....
>
> (: build test case :)
> let $names :=
> for $i in 1 to 8
> return codepoints-to-string(string-to-codepoints("a") - 1 + $i)
> for $i in 1 to 100
> let $name-index := 1 + $i count($names)
> let $id := concat("t", string($i))
> let $uri := concat("test/", string($i))
> return
> xdmp:document-insert(
> $uri,
> element { $names[$name-index] } {
> attribute xml:id { $id },
> xdmp:integer-to-hex(xdmp:random())
> })
>
> This inserts 100 docs that look like:
>
> ...
> <a xml:id="t16">39c5218f30d8434f</a>
> <b xml:id="t17">74fb0615f8a17110</b>
> <c xml:id="t10">53439ea8dd47f4d0</c>
> <d xml:id="t11">828dd36894cfa367</d>
> <e xml:id="t12">87d537f4eb96e1b0</e>
> <f xml:id="t13">154eea3e15b59fcf</f>
> <g xml:id="t14">701dfd435977a3fc</g>
> <h xml:id="t15">39842113ea1e916e</h>
> ...
>
> I can query these documents efficiently using XPath:
>
> /(a|b|c|d|e|f|g|h)[...@xml:id eq "t1"]
> =>
> <b xml:id="t1">60271146593168d7</b>
>
> According to xdmp:query-trace(), this selects 1 fragment to filter. We
> can also write this query in a few other ways. For example, I might want
> to store a list of all the possible QNames in a variable, so that I can
> compose the query more dynamically:
>
> let $names :=
> for $i in 1 to 8
> return xs:QName(codepoints-to-string(string-to-codepoints('a') - 1 + $i))
> return /*[node-name(.) = $name...@xml:id eq "t1"]
>
> We can use a similar technique with a cts:query:
>
> let $q :=
> cts:element-attribute-value-query(
> for $i in 1 to 8
> return
> xs:QName(
> codepoints-to-string(
> string-to-codepoints("a") - 1 + $i)),
> xs:QName("xml:id"),
> "t1")
> return cts:search(doc(), $q)
>
> All three of these forms are efficient.
>
> thanks,
> -- Mike
>
> On 2009-07-20 19:02, Tim Finney wrote:
> > Dear All,
> >
> > I would like to be able to find the element associated with an @xml:id
> > quickly, without knowing the element path or name. Can this be done with
> > MarkLogic?
> >
> > The id() function is meant to do this but it is horribly slow when faced
> > with masses of documents. For example,
> >
> > collection()//*...@xml:id eq 'something']
> >
> > takes thirty seconds and I need it to work in hundredths of seconds
> > instead.
> >
> > (If I put in the element name, the above query runs in about a hundredth
> > of a second.)
> >
> > Best,
> >
> > Tim Finney
> > University of Virginia Press
> >
> >
> > _______________________________________________
> > General mailing list
> > [email protected]
> > http://xqzone.com/mailman/listinfo/general
>
> _______________________________________________
> General mailing list
> [email protected]
> http://xqzone.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
http://xqzone.com/mailman/listinfo/general