As yet another alternative, I'd suggest a slight tweak to your original
example:
Change this:
collection("metadata")/*[dt:identifier = $id]
To this:
collection("metadata")[*/dt:identifier = $id]
Don't ask me why the latter is faster, but if you wrap xdmp:plan() around
each of the above in Query Console, you'll see proof of this. In the first
case, all fragments (documents) in the collection are selected, whereas in
the second, the index resolution should get you all the way there
(requiring no excessive filtering):
<qry:info-trace>Step 1 predicate 1 contributed 1 constraint:
*/dt:identifier = "foo"</qry:info-trace>
I'll file a bug/RFE to request better optimization in the first (more
natural) case.
Evan Lenz
Software Developer, Community
MarkLogic Corporation
http://community.marklogic.com
On 5/9/12 2:13 PM, "Danny Sokolsky" <[email protected]> wrote:
>As an alternate, I wonder if you can do this as a URI lexicon query? For
>example:
>
>fn:doc(
> cts:uri-match(fn:concat("/content/*/", $id, ".xml"), (),
> cts:and-query((
> cts:collection-query("metadata"),
> cts:element-value-query(xs:QName("dt:identifier"), $id) )) ) )
>
>-Danny
>
>-----Original Message-----
>From: [email protected]
>[mailto:[email protected]] On Behalf Of Michael
>Blakeley
>Sent: Wednesday, May 09, 2012 1:56 PM
>To: MarkLogic Developer Discussion
>Cc: General Mark Logic Developer Discussion
>Subject: Re: [MarkLogic Dev General] alternative ways to access documents
>
>You are fetching the document twice, aren't you? Try this:
>
> collection("metadata")//dt:identifier[. = $id]/root()
>
>I don't really like using // but in this case it may be the best option.
>
>-- Mike
>
>On May 9, 2012, at 13:37, Jakob Fix <[email protected]> wrote:
>
>> Hi,
>>
>> So far I've been successfully using
>> document("/content/[type]/[id].xml") to efficiently access a document.
>> This worked because I had both the [type] and the [id] values that
>> make up the path and the filename.
>>
>> Now my scenario has changed and I no longer know the [type] bit of the
>> path. For convenience I still want to store all documents belonging
>> to a given [type] in the corresponding subdirectory (although this may
>> be negotiable).
>>
>> The only way that I've found so far, and which is horribly inefficient
>> is to look inside the document for the [id] value, like so:
>>
>> let $doc as node() :=
>> document(xdmp:node-uri(collection("metadata")/*[dt:identifier = $id]))
>>
>> A document has a type specific root element (such as Book, Article,
>> ...), and as one if its children the <dt:identifier> element. This
>> takes consistently longer than a second to execute.
>>
>> I've considered and rejected creating a specific collection for each
>> identifier, i.e. I would end up with one collection per element which
>> seems to be counter the concept of collections which is intended to
>> regroup documents with common properties.
>>
>> I appreciate your input.
>>
>> cheers,
>> Jakob.
>> _______________________________________________
>> 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