Reputation: 396
I have a query for fetching autosuggest from xml, it works fine for 3 or more characters.. but is extremely slow for 1 or 2 characters..
Here's the xquery which I'm using, any correction would be appreciated..
xquery version "1.0-ml";
declare default function namespace "local";
declare default collation "http://marklogic.com/collation/en/S1";
declare variable $search-term := xdmp:get-request-field("query", "b");
declare function getWildCardedTerm($term as xs:string) as xs:string*{
(fn:concat($search-term, "*"),fn:concat("* ",$search-term))
};
let $terms := getWildCardedTerm($search-term)
let $values := cts:search(//searchLabel,cts:and-query((cts:collection-query(("/collections/autosuggest")), cts:element-word-query(xs:QName("suggestion"),$terms))) )
let $suggestionsOrderedByLength := for $value in $values
order by fn:string-length($value//altLabel/text()), $value/altLabel/text()
return $value
return <suggestions>{$suggestionsOrderedByLength[1 to 10]}</suggestions>
Is there a way where to sort during search??
Upvotes: 0
Views: 83
Reputation: 20414
The Search Developer's Guide recommends combining the trailing wildcard searches
with a word lexicon
. You also have three/two/one character searches
options you may not have enabled yet, but they will require substantial extra disk space.
But I'm afraid that MarkLogic indexes and lexicons are not particularly optimized for this use case. You can get frequency-order
and item-order
values directly from range indexes using cts:values
, but not values ordered by length. If it would, you could have used that with a cts:index-order
to apply sorting to your cts:search
.
I would recommend taking a look at cts:value-match
though, and apply that to your suggestion
element. It will only require a range index, and no further settings. It will also not pull actual fragments from disk like cts:search
, and run from in-memory data entirely. That will likely be faster..
HTH!
Upvotes: 2