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
> 


Reply via email to