How to do sorting for specific values in Xquery?

Viewed 27
<doc>
<a name='123'>AAAAA</a>
</doc>

<doc>
<a name='123'>BBBB</a>
</doc>

<doc>
<a name='111'>CCCC</a>
</doc>

<doc>
<a name='110'>EEEE</a>
</doc>

<doc>
<a name='100'>DDDD</a>
</doc>

I want to do sorting on element "a" but only where name=123, remaining doc should come randomly. I would prefer using cts query if possible.

1 Answers

If you have an index on the a element, then you could use two searches. The first one searching for a/@name=123 and sorting the results by the a with cts:index-order() and a cts:element-reference(). Then, a second search for the rest that do not have a/name=123 returned by the default sort order.

(: substitute with whatever query identifies this set of docs :)
let $base-query := cts:element-attribute-value-query(xs:QName("a"), xs:QName("name"), "*", "wildcarded") 
let $sorted-name-query := cts:element-attribute-value-query(xs:QName("a"), xs:QName("name"), "123")

let $sorted-results := (
  cts:search(doc(), 
    cts:and-query(( $base-query, $sorted-name-query )), 
    cts:index-order(cts:element-reference(xs:QName("a"))) ),
  cts:search(doc(), cts:and-not-query($base-query, $sorted-name-query))
)

Or you could perform the sorting with the ORDER BY clause of a FLWOR:

(: substitute with whatever query identifies this set of docs :)
let $base-query := cts:element-attribute-value-query(xs:QName("a"), xs:QName("name"), "*", "wildcarded") 

let $sorted-results := 
  for $doc in cts:search(doc(), $base-query)
  order by $doc/a[@name=123], xdmp:random()
  return $doc 
Related