Hi Christian, I refactored my xquery and it's now running very smooth, faster than ever. Thanks a lot for your great help. I also followed your advice, creating a new index just for the full-text-search in mixed-content-environments. This approach is solving a lot of problems I had in the past... Thanks again.
I want to use also your programmatic way to specify full-text options only once in the query, cause it would make my code much cleaner: let $ft := map { 'wildcards': true() } let $terms := 'pa.*' for $city in ft:search('factbook', $terms, $ft)/parent::name[ancestor::city] let $hits := ft:mark($city[ft:contains(text(), $terms, $ft)]) return let $name := $city/ancestor::country/name return ($hits, $name) The $options argument in ft:search has most the full-text options, I need. The only problem left is, to integrate the full-text options 'case sensitive' and 'diacritics sensitive'. Is there any way, to get those options inside the ft:search function? Günter > Am 05.01.2016 um 19:56 schrieb Christian Grün <christian.gr...@gmail.com>: > > Hi Günter, > > I had one more look at the slow query you were encountering: > >> for $city in doc('factbook')//city/name >> for $hits in ft:mark($city[.//text() contains text {$query} using wildcards]) >> let $country_of_city := $city/ancestor::country/name >> return >> (: slow version: Evaluating 35.78 :) >> (: <hit><city>{$hits}</city><country>{$country_of_city}</country></hit> :) > > This one was more tricky than I expected, because the ft:mark function > can produce multiple results for a single node. This is why the > sliding of the let clause, which slows down your query, can be > beneficial in other cases. The following query will generate 20 > results (10 "mark" elements, 10 text nodes), so it will be evaluated > faster if the let clause is slided over the for clause: > > let $input := (<X>{ 'A.A.A.A.A.A.A.A.A.A.' }</X> update () )/text() > for $hits in ft:mark($input[. contains text 'A']) > let $parent := $input/.. > return <hit id='{ db:node-id($parent) }'>{ $hits }</hit> > > Well, those are lots of internal details that I think you can easily > ignore. In a nutshell: Just use 'let' and 'where' instead tof 'for': > > let $input := (<X>{ 'A.A.A.A.A.A.A.A.A.A.' }</X> update () )/text() > let $hits := ft:mark($input[. contains text 'A']) > where $hits > let $parent := $input/.. > return <hit id='{ db:node-id($parent) }'>{ $hits }</hit> > > Christian >