0

I have constraints like below.. with a constraint

<options xmlns="http://marklogic.com/appservices/search">
    <additional-query>
        <cts:and-query xmlns:cts="http://marklogic.com/cts">
            <cts:collection-query>
                <cts:uri>OncoWatch</cts:uri>
            </cts:collection-query>
        </cts:and-query>
    </additional-query>
    <constraint name="search-text">
        <word>
            <field name="wos_topic"/>
        </word>
    </constraint>
    <term>
        <term-option>case-insensitive</term-option>
        <term-option>punctuation-insensitive</term-option>
        <term-option>whitespace-insensitive</term-option>
        <term-option>wildcarded</term-option>
    </term>
</options>

When I do the search string '(search-text:(patient* OR adult*))' I get results completely different from when I do this '(search-text:patient*) OR (search-text:adult*)'.. Isn't both the same ?

grtjn
  • 20,254
  • 1
  • 24
  • 35
Ravi
  • 1,179
  • 6
  • 13

1 Answers1

2

You can easily see the difference if you apply search:parse on your search strings:

xquery version "1.0-ml";

import module namespace search = "http://marklogic.com/appservices/search"
     at "/MarkLogic/appservices/search/search.xqy";

let $options := <options xmlns="http://marklogic.com/appservices/search">
    <additional-query>
        <cts:and-query xmlns:cts="http://marklogic.com/cts">
            <cts:collection-query>
                <cts:uri>OncoWatch</cts:uri>
            </cts:collection-query>
        </cts:and-query>
    </additional-query>
    <constraint name="search-text">
        <word>
            <field name="wos_topic"/>
        </word>
    </constraint>
    <term>
        <term-option>case-insensitive</term-option>
        <term-option>punctuation-insensitive</term-option>
        <term-option>whitespace-insensitive</term-option>
        <term-option>wildcarded</term-option>
    </term>
</options>
return (
  search:parse("(search-text:(patient* OR adult*))", $options),
  search:parse("(search-text:patient*) OR (search-text:adult*)", $options)
)

The search parser supports fairly complex search strings with AND, OR, NEAR, etc, but the support for feeding multiple values into a single constraint is lacking. The latter is the right way of writing it. The first simply gets the parser confused from the looks of it, and as a result the OR gets lost, effectively causing it to search for the phrase search-text:"patient* adult*" which is kind of the same as requiring both terms.

HTH!

grtjn
  • 20,254
  • 1
  • 24
  • 35
  • Using cts:parse might be another option. Unlike the Search API string query grammar, the cts string query grammar enables you to apply a constraint to a list. See http://docs.marklogic.com/guide/search-dev/cts_query#id_71878. – kcoleman Aug 11 '18 at 23:31
  • Additionally I found this answer to be helpful: https://stackoverflow.com/a/45291022/3546482 – Fan Li Mar 25 '19 at 11:56