2

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?

mblakele
  • 7,782
  • 27
  • 45
Ben Aston
  • 53,718
  • 65
  • 205
  • 331

1 Answers1

3

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 { . }
Ben Aston
  • 53,718
  • 65
  • 205
  • 331
wst
  • 11,681
  • 1
  • 24
  • 39
  • 2
    Excellent answer, but a `cts:element-value-query` may perform better than the nested `cts:element-query` and `cts:word-query`. Also, given the call to `document-uri` it might be even better to use `cts:uris` rather than `cts:search`: http://stackoverflow.com/a/17710863/908390 has an example. – mblakele Jul 22 '13 at 21:47