Amit Gope
Amit Gope

Reputation: 130

Result Set manipulation with search-api in Marklogic

I am working with search-api and wanted to know how to manipulate the search result on the fly? I need something like this:

I need to sort my result set on the basis of some criteria and if the value of the criteria is null then I should apply some arbitrary integer value so that I dont get the xdmp:cast exception.

Please help.

Regards Amit

Upvotes: 0

Views: 219

Answers (3)

Tyler Replogle
Tyler Replogle

Reputation: 1339

try using empty least (http://www.w3.org/TR/xquery/#id-orderby-return). That should make it so your null values show up last.

for $each in $x/ArticleSequenceNumber
stable order by xs:integer($each) empty least
return $each 

if you put a ranged index on ArticleSequenceNumber and do the sorting in the right place you'll get the sorting coming off of the indexs.

Upvotes: 0

mblakele
mblakele

Reputation: 7840

Each re-sort will require a fresh API call - search:search or search:resolve. You can set the search options appropriately for the sort key.

Fixing an XDMP-CAST exception requires a fix for the underlying datatype problem. What is the complete error message?

EDIT: As written, you could use something like this to handle non-integer values.

for $each in $x/ArticleSequenceNumber
order by
  if ($each castable as xs:integer) then xs:integer($each)
  else 0
return $each

But the search API does not handle that kind of thing. The search API is designed around large databases, where the search results are too large to fit in-memory all at once. So it expects to have range indexes available for sorting. Range indexes, in turn, depend on having clean input data.

The usual solution is to clean up your ArticleSequenceNumber element if you want to use it as a sort key with the search API. When the element would be empty, give it a dummy value or drop it from the XML entirely.

However, http://markmail.org/message/53pn6xioluwxdx4o might help. The idea here is to treat the values as strings instead of numbers, but sort them using a numeric collation.

for $each in $x/ArticleSequenceNumber
order by $each collation "http://marklogic.com/collation//MO"
return $each

You should be able to specify that same collation in your search constraint. The corresponding range index will be a string index with that same collation.

Upvotes: 1

Amit Gope
Amit Gope

Reputation: 130

xquery version '1.0-ml';
let $x := <root>
<ArticleSequenceNumber/>
<ArticleSequenceNumber>1</ArticleSequenceNumber>
<ArticleSequenceNumber>5</ArticleSequenceNumber>
<ArticleSequenceNumber>10</ArticleSequenceNumber>
<ArticleSequenceNumber>63</ArticleSequenceNumber>
<ArticleSequenceNumber>54</ArticleSequenceNumber>
<ArticleSequenceNumber>19</ArticleSequenceNumber>
<ArticleSequenceNumber>21</ArticleSequenceNumber>
<ArticleSequenceNumber>29</ArticleSequenceNumber>
<ArticleSequenceNumber>11</ArticleSequenceNumber>
</root>
for $each in $x/ArticleSequenceNumber
order by xs:integer($each)
return $each

Upvotes: 0

Related Questions