Moving where into cts:search

785 views Asked by At

Given this query:

for $d in cts:search(
      fn:doc(),
      cts:and-query(
       (            
         cts:collection-query(('InProgress_Audit'))
       )
      ))          
      where not(fn:contains($d//TitleDate/text(),"Z"))
      return <p>{document-uri($d)}</p>

How do I move the "where" constraint into the CTS search query?

1

There are 1 answers

1
wst On BEST ANSWER

This uses cts:query to apply your constraints:

for $d in cts:search(
  fn:doc(),
  cts:and-not-query(            
     cts:collection-query('InProgress_Audit'),
     cts:element-query(xs:QName('TitleDate'),
       cts:word-query('*Z*', 'wildcarded'))
  ))
return <p>{document-uri($d)}</p>

There are index options to speed up wildcarded searches. You could also use a range index on TitleDate in combination with a cts:element-range-index-query to speed this up even further.

Update: As @mblakele points out in the comments, cts:element-value-query may be faster than the nested cts:element-query/cts:word-query:

cts:element-value-query(xs:QName('TitleDate'), '*Z*', 'wildcarded')

And using cts:uris will be faster than making many repeated calls to document-uri(). However, you would need to enable the URI lexicon option in your settings. Putting all that together, the query would look like:

cts:uris((), 'document',
  cts:and-not-query((            
     cts:collection-query('InProgress_Audit'),
     cts:element-value-query(xs:QName('TitleDate'), 
       '*Z*', 'wildcarded')
  ))) ! element p { . }