I forgot to mention that I use this solution in a generic REST API solution
only available for internal developpers so code injection wasn't my major
concern.
But I'll try the dynamic name lookup to improve performance and it's indeed a
better practice.
Is there a likewise solution for passing dynamically a xpath filter to a
collection?
e.g. collection('mycollection')/field[value = 'avalue']
where field[value='avalue'] can be any xpath expression ?
-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of
[email protected]
Sent: dinsdag 5 mei 2015 18:57
To: [email protected]
Subject: General Digest, Vol 131, Issue 34
Send General mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://developer.marklogic.com/mailman/listinfo/general
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific than "Re:
Contents of General digest..."
Today's Topics:
1. Re: Dynamic order by (message 4) (David Lee)
----------------------------------------------------------------------
Message: 1
Date: Tue, 5 May 2015 16:56:36 +0000
From: David Lee <[email protected]>
Subject: Re: [MarkLogic Dev General] Dynamic order by (message 4)
To: MarkLogic Developer Discussion <[email protected]>
Message-ID:
<6ad72d76c2d6f04d8be471b70d4b991e0bc95...@exchg10-be01.marklogic.com>
Content-Type: text/plain; charset="us-ascii"
' xdmp:eval and building the xquery order string through a function.'
xdmp:eval() should be avoided if at all possible, especially with dynamically
created string content its
incurs a significant overhead and opens the possibility of XQuery injection.
eval and invoke are intended for when you need contextual changes otherwise
impossible (such as a new transaction,
running in a different module or DB etc).
*almost* anything else you can do with XQuery 3.x named and anonymous functions
much easier, safer and faster.
First consider that use of indexes and cts:search or search:search may
implement what you want much better then XPath
and may not require an order-by depending on the range indexes.
search:search directly allows runtime sort order :
https://docs.marklogic.com/search:search
See:
<sort-order>
Set the default sort order. The first such element is the primary sort order,
the second secondary sort order, and so on. The default is to sort by score,
descending. Note that the default scoring algorithm can be set just like any
other option with the option named search-option. If you are sorting by an
element or an attribute, you must specify a type attribute with a value
corresponding to the range index type of that element or attribute (for
example, xs:string, xs:dateTime, and so on). If the corresponding range index
is of type xs:string, then you can optionally specify a collation attribute
(otherwise the collation of the query is used). To change the sorting
direction, specify an optional directionattribute with a value of decending
(the default) or ascending.
The sort-order element must have one of a single element child, a single score
child, a single field child, or a single json-property child. If there is a
score child, it specifies to sort by the score of the search result. If there
is an element child it can optionally have an attribute sibling (to specify an
attribute of the preceding element). Both the element and attribute elements
must have ns and name attributes to specify the namespace and local-name of the
specified element and attribute. Additionally, the sort-order element can have
0 or more annotation elements (to add comments, for example). You should not
apply sort-order to a field backed by a field range index with more than one
included element.
For example, the following specifies a primary sort order using the element
value for my-element (which needs a string range index with the specified
collation), and a secondary sort order of score ascending:
<sort-order type="xs:string"
collation="http://marklogic.com/collation/"
direction="ascending">
<element ns="my-namespace" name="my-element"/>
<annotation>some user comment can go here</annotation> </sort-order>
<sort-order direction="ascending">
<score/>
</sort-order>
The search library is very powerful and adopts 'best practice' over a large
range of features.
If that doesnt work ...
Are your element names from an infinate unknown set (i.e literally any name
might be used),
or are they from a fixed set (>1) ?
If its a compile time fixed set you can do some optimizations, including making
range indexes over the
sort fields ...
--- Here are some examples to play with - not your exact structure, I used this
code to generate 10000 docs with 10 items of E{1...10} each
xdmp:document-delete(cts:uris());
declare variable $qn := ( 1 to 10 ) ! fn:QName( "" , "E" || . );
for $i in 1 to 10000
return xdmp:document-insert( "/test."||$i||".xml" ,
<doc>{
for $item in 1 to 10
return
<item> {
for $q in $qn return
element { $q } { xdmp:random(100) } ,
<value>The items value is: {$item}</value>
}</item>
}
</doc> )
------------ And here's a test program showing some different ways of doing
things ---
Adding a range index to all the E* items helped a lot in some of the tests but
not others.
This case I used a trick to simplify the ascending/descending case - the values
are numeric so multiple by 1/-1
For text you may need to replicate the functions for ascending or descending or
reverse the results afterwards.
In all these cases - performance will be improved dramatically if you can
*first* filter the set of possible documents
before doing the sort -
declare variable $sort-name external := "E5" ;
declare variable $sort-elem external := element { xs:QName($sort-name) } {} ;
declare variable $sort-order external := 1;
(: Dynamic name lookup :)
declare variable $compare1:=
function( $result as element() ) as xs:double {
$result/*[fn:local-name() eq $sort-name]/fn:data() * $sort-order
};
(: faster static lookup :)
declare variable $compare2:=
function( $result as element() ) as xs:double {
typeswitch( $sort-elem )
case element( E1 ) return $result/E1
case element( E2 ) return $result/E2
case element( E3 ) return $result/E3
case element( E4 ) return $result/E4
case element( E5 ) return $result/E5
case element( E6 ) return $result/E6
case element( E7 ) return $result/E7
case element( E8 ) return $result/E8
case element( E9 ) return $result/E9
case element( E10 ) return $result/E10
default return fn:error( () , "Unknown element : " , $sort-elem )
/ fn:data() * $sort-order
};
declare function local:test( ) {
for $result in (/doc/*)
order by $result/E5 ascending
return $result/value
};
declare function local:test1( ) {
for $result in (/doc/*)
order by $compare1( $result )
return $result/value
};
declare function local:test2( ) {
for $result in (/doc/*)
order by $compare2( $result )
return $result/value
};
declare function local:test3()
{
for $result in (/doc/*)
order by
typeswitch( $sort-elem )
case element( E1 ) return $result/E1
case element( E2 ) return $result/E2
case element( E3 ) return $result/E3
case element( E4 ) return $result/E4
case element( E5 ) return $result/E5
case element( E6 ) return $result/E6
case element( E7 ) return $result/E7
case element( E8 ) return $result/E8
case element( E9 ) return $result/E9
case element( E10 ) return $result/E10
default return fn:error( () , "Unknown element : " , $sort-elem )
/ fn:data() * $sort-order
return $result/value
};
-----------------------------------------------------------------------------
David Lee
Lead Engineer
MarkLogic Corporation
[email protected]
Phone: +1 812-482-5224
Cell: +1 812-630-7622
www.marklogic.com
-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Vanheeswijck David
Sent: Tuesday, May 05, 2015 5:03 AM
To: [email protected]
Subject: Re: [MarkLogic Dev General] Dynamic order by (message 4)
I've solved this by using xdmp:eval and building the xquery order string
through a function.
Do you need an example ?
------------------------------
Message: 4
Date: Tue, 5 May 2015 04:04:45 +0000
From: "Kapoor, Pragya" <[email protected]<mailto:[email protected]>>
Subject: Re: [MarkLogic Dev General] Dynamic order by
To: MarkLogic Developer Discussion
<[email protected]<mailto:[email protected]>>
Message-ID:
<[email protected]<mailto:[email protected]>>
Content-Type: text/plain; charset="utf-8"
Could someone help on this?
________________________________
From: Kapoor, Pragya
Sent: Monday, May 4, 2015 5:03 PM
To: MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] Dynamic order by
Thanks Asit.
But I have different requirement.
In your code :
return if($sorting/sorting/sort) then
for $each in $results//results/result
order by $each/AgreementType descending , $each/CollectionNo ascending return
$each (: modify as per your business requirement :) else $results
In the order by clause you are using $each/AgreementType, but as mentioned in
the mail the element AgreementType is not static. This value is dynamic
moreover sort direction(asc/desc) is also dynamic.
?Thanks
Pragya
________________________________
From:
[email protected]<mailto:[email protected]>
<[email protected]<mailto:[email protected]>>
on behalf of Asitmohan Nautiyal
<[email protected]<mailto:[email protected]>>
Sent: Monday, May 4, 2015 4:40 PM
To: MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] Dynamic order by
Hi Pragya,
try below sample code
let $sorting :=<a> <sorting>
<columnAlias>Currency</columnAlias>
</sorting>
<sorting>
<sort>desc</sort>
<columnAlias>AgreementType</columnAlias>
</sorting>
<sorting>
<sort>asc</sort>
<columnAlias>CollectionNo</columnAlias>
</sorting></a>
let $results :=
<report>
<columns>
<title>Currency</title>
<title>AgreementType</title>
<title>CollectionNo</title>
</columns>
<results>
<result>
<Currency>US dollar</Currency>
<AgreementType>abc</AgreementType>
<CollectionNo>0000050</CollectionNo>
</result>
<result>
<Currency>Pound sterling</Currency>
<AgreementType>xyz</AgreementType>
<CollectionNo>0000048</CollectionNo>
</result>
<result>
<Currency>Euro</Currency>
<AgreementType>ebf</AgreementType>
<CollectionNo>0000049</CollectionNo>
</result>
</results>
</report>
return if($sorting/sorting/sort) then
for $each in $results//results/result
order by $each/AgreementType descending , $each/CollectionNo ascending return
$each (: modify as per your business requirement :) else $results
Regards,
Asit Nautiyal
________________________________
From:
[email protected]<mailto:[email protected]>
[[email protected]] on behalf of Kapoor, Pragya
[[email protected]]
Sent: Monday, May 04, 2015 3:21 PM
To: MarkLogic Developer Discussion
Subject: [MarkLogic Dev General] Dynamic order by
Hi,
I need to sort the $results based on element columnAlias in $sorting.
for eg :
In the below scenario, I want to first sort the $results with
AgreementType(desc) and then with CollectionNo(asc).If there is not <sort>
element in $sorting/sorting then do not use that element <columnAlias> for
sorting.
Moreover the elements in $sorting & $results will be dynamic and not fixed.
let $sorting :=<a> <sorting>
<columnAlias>Currency</columnAlias>
</sorting>
<sorting>
<sort>desc</sort>
<columnAlias>AgreementType</columnAlias>
</sorting>
<sorting>
<sort>asc</sort>
<columnAlias>CollectionNo</columnAlias>
</sorting></a>
let $results :=
<report>
<columns>
<title>Currency</title>
<title>AgreementType</title>
<title>CollectionNo</title>
</columns>
<results>
<result>
<Currency>US dollar</Currency>
<AgreementType>abc</AgreementType>
<CollectionNo>0000050</CollectionNo>
</result>
<result>
<Currency>Pound sterling</Currency>
<AgreementType>xyz</AgreementType>
<CollectionNo>0000048</CollectionNo>
</result>
<result>
<Currency>Euro</Currency>
<AgreementType>ebf</AgreementType>
<CollectionNo>0000049</CollectionNo>
</result>
</results>
</report>
Thanks
Pragya
?
"This e-mail and any attachments transmitted with it are for the sole use of
the intended recipient(s) and may contain confidential , proprietary or
privileged information. If you are not the intended recipient, please contact
the sender by reply e-mail and destroy all copies of the original message. Any
unauthorized review, use, disclosure, dissemination, forwarding, printing or
copying of this e-mail or any action taken in reliance on this e-mail is
strictly prohibited and may be unlawful."
::DISCLAIMER::
----------------------------------------------------------------------------------------------------------------------------------------------------
The contents of this e-mail and any attachment(s) are confidential and intended
for the named recipient(s) only.
E-mail transmission is not guaranteed to be secure or error-free as information
could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or
may contain viruses in transmission. The e mail and its contents (with or
without referred errors) shall therefore not attach any liability on the
originator or HCL or its affiliates.
Views or opinions, if any, presented in this email are solely those of the
author and may not necessarily reflect the views or opinions of HCL or its
affiliates. Any form of reproduction, dissemination, copying, disclosure,
modification, distribution and / or publication of this message without the
prior written consent of authorized representative of HCL is strictly
prohibited. If you have received this email in error please delete it and
notify the sender immediately.
Before opening any email and/or attachments, please check them for viruses and
other defects.
----------------------------------------------------------------------------------------------------------------------------------------------------
"This e-mail and any attachments transmitted with it are for the sole use of
the intended recipient(s) and may contain confidential , proprietary or
privileged information. If you are not the intended recipient, please contact
the sender by reply e-mail and destroy all copies of the original message. Any
unauthorized review, use, disclosure, dissemination, forwarding, printing or
copying of this e-mail or any action taken in reliance on this e-mail is
strictly prohibited and may be unlawful."
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://developer.marklogic.com/pipermail/general/attachments/20150505/227a8999/attachment.html
------------------------------
_______________________________________________
General mailing list
[email protected]<mailto:[email protected]>
Manage your subscription at:
http://developer.marklogic.com/mailman/listinfo/general
End of General Digest, Vol 131, Issue 27
****************************************
_______________________________________________
General mailing list
[email protected]<mailto:[email protected]>
Manage your subscription at:
http://developer.marklogic.com/mailman/listinfo/general
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://developer.marklogic.com/pipermail/general/attachments/20150505/f1b2a12d/attachment.html
------------------------------
_______________________________________________
General mailing list
[email protected]
Manage your subscription at:
http://developer.marklogic.com/mailman/listinfo/general
End of General Digest, Vol 131, Issue 34
****************************************
_______________________________________________
General mailing list
[email protected]
Manage your subscription at:
http://developer.marklogic.com/mailman/listinfo/general