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