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?
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 { . }