I'm encountering a very strange issue with MarkLogic's search:search() function. When using a constraint option, it seems like it does not sort by score correctly. Below is an edited version of the function I am calling to search:
declare function s:book-search(
$query as xs:string*,
$subjects as xs:string*,
$start as xs:unsignedLong?,
$page-length as xs:unsignedLong?) as element(search:response){
let $subject-ids := fn:tokenize($subjects, ',')
let $subject-query :=
if(fn:count($subject-ids) > 0)
then
for $id in $subject-ids
return 'metadata/subject/'||$id
else
()
let $options :=
<options xmlns="http://marklogic.com/appservices/search">
<searchable-expression xmlns:m="http://replacedrealwebsite.com/collection/book-metadata">
/m:metadata
</searchable-expression>
<constraint name="subject">
<collection prefix="metadata/subject/" facet="true" />
</constraint>
{
if(fn:count($subject-query) > 0)
then
<additional-query>{cts:collection-query($subject-query)}</additional-query>
else
()
}
<term>
<term-option>case-insensitive</term-option>
<term-option>diacritic-insensitive</term-option>
<term-option>punctuation-insensitive</term-option>
</term>
<sort-order direction="descending">
<score/>
</sort-order>
<transform-results apply="empty-snippet"/>
<search-option>unfiltered</search-option>
</options>
return search:search($query, $options, $start, $page-length)
};
If I pass any $subjects in, without a $query parameter, the results are ordered incorrectly, but also ordered in a strange manner. For example, here is a list of the scores in the order they were returned from a test call with a large page length to see all the results:
[
"7808768",
"334592",
"285952",
"197120",
"113408",
"74496",
"34816",
"7808256",
"7705856",
"7694592",
"2031360",
"1144832",
"629504",
"181760",
"145664",
"70656",
"62208",
"57856",
"-208384",
"8101632",
"7853056",
...
]
As you can see, the highest score is not the first result. Additionally, it sorts in descending order, but then it will "jump" up to a high score, and then descend again. I can't seem to identify any pattern or order.
What makes this stranger is that if I add a non-blank $query parameter, the scores are ordered correctly! Here is an example of the scores when I pass in a simple word to the $query parameter:
[
"8403200",
"8154624",
"8153856",
"8110336",
"8109824",
"8007424",
"7988992",
"7982080",
"5464320",
"2332928",
"1456128",
"931072",
"587520",
"509440",
"483328",
"447232",
"435200",
"429312",
"424704",
"381952",
"376064",
"373504",
...
]
I've been trying to fiddle with the search options for a while and am at a loss as to why this is happening. Any ideas would be greatly appreciated.
The MarkLogic version I'm running on is 10.0-6.4
I should also note that this issue is not happening on a test server running 10.0 with identical code, which makes me think this is a bug with MarkLogic or a small difference between versions that I'm missing.
Edit: Another odd thing that I've noticed is that if I change the sort to
<sort-order direction="ascending">
<score/>
</sort-order>
then the results are returned in the correct ascending order. So it is only descending order that is broken.