2 votes

Problème d'utilisation de cts:not-query ou cts:and-not-query

Ma version de MarkLogic est la 9. J'ai deux requêtes qui renvoient des résultats attendus lorsqu'elles sont exécutées séparément, mais lorsque j'essaie de les combiner, je n'obtiens aucun résultat.

Mes données ressemblent à ce qui suit, je dois faire correspondre seulement ABC, pas ABC/* (ou ABC/D si c'est le critère recherché et dans ce cas, pas ABC/D/*).

<root xmlns:ns1="http://ns1"> 
   <ns1:security>
     <ns1:elem>ABC</ns1:elem>
     <ns1:elem>ABC/D</ns1:elem>
     <ns1:elem>ABC/D/E</ns1:elem>
   </ns1:security>
</root>

Le code ci-dessous renvoie 4 résultats

xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";

search:resolve(        
        <cts:path-range-query operator="=" xmlns:ns1="http://ns1">
          <cts:path-expression>//ns1:security/ns1:elem</cts:path-expression>
          <cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">ABC</cts:value>
        </cts:path-range-query>
)

et celui-ci seulement 3 résultats

xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";

search:resolve( 
      <cts:element-query>
        <cts:element xmlns:ns1="http://ns1">ns1:security</cts:element>
        <cts:element-value-query>
          <cts:element xmlns:ns1="http://ns1">ns1:elem</cts:element>
          <cts:text xml:lang="en">ABC/*</cts:text>
          <cts:option>wildcarded</cts:option>
        </cts:element-value-query>
      </cts:element-query>
)

Je m'attendais donc à obtenir 1 résultat en exécutant ceci

xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";

search:resolve(
    <cts:and-not-query>

      <cts:positive>  
        <cts:path-range-query operator="=" xmlns:ns1="http://ns1">
          <cts:path-expression>//ns1:security/ns1:elem</cts:path-expression>
          <cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">ABC</cts:value>
        </cts:path-range-query>
      </cts:positive>

      <cts:negative>
        <cts:element-query>
          <cts:element xmlns:ns1="http://ns1">ns1:security</cts:element>
          <cts:element-value-query>
            <cts:element xmlns:ns1="http://ns1">ns1:elem</cts:element>
            <cts:text xml:lang="en">ABC/*</cts:text>
            <cts:option>wildcarded</cts:option>
          </cts:element-value-query>
        </cts:element-query>

      </cts:negative>      
    </cts:and-not-query>
)

J'ai aussi essayé ceci mais le résultat est le même

xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";

search:resolve(
    <cts:and-query>

      <cts:path-range-query operator="=" xmlns:ns1="http://ns1">
        <cts:path-expression>//ns1:security/ns1:elem</cts:path-expression>
        <cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">ABC</cts:value>
      </cts:path-range-query>

      <cts:not-query>
        <cts:element-query>
          <cts:element xmlns:ns1="http://ns1">ns1:security</cts:element>
          <cts:element-value-query>
            <cts:element xmlns:ns1="http://ns1">ns1:elem</cts:element>
            <cts:text xml:lang="en">ABC/*</cts:text>
            <cts:option>wildcarded</cts:option>
          </cts:element-value-query>
        </cts:element-query>
      </cts:not-query>

    </cts:and-query>
)

S'agit-il d'un bogue connu ? Est-ce que je fais quelque chose de mal ici ? Toute aide est appréciée :)

Plan de recherche

<search:response snippet-format="snippet" total="0" start="1" page-length="10" xmlns:search="http://marklogic.com/appservices/search">
  <search:plan>
    <qry:query-plan xmlns:qry="http://marklogic.com/cts/query">
      <qry:expr-trace>impl:apply-search(map:map(&lt;map:map xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" .../&gt;), "xdmp:plan", fn:false())</qry:expr-trace>
      <qry:info-trace>Analyzing path for search: fn:collection()</qry:info-trace>
      <qry:info-trace>Step 1 is searchable: fn:collection()</qry:info-trace>
      <qry:info-trace>Path is fully searchable.</qry:info-trace>
      <qry:info-trace>Gathering constraints.</qry:info-trace>
      <qry:info-trace>Comparison contributed string range value constraint: //ns1:security/ns1:elem = "CTPA"</qry:info-trace>
      <qry:partial-plan>
    <qry:range-query weight="0" min-occurs="1" max-occurs="4294967295" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <qry:key>12785637774270294680</qry:key>
      <qry:annotation>path(//ns1:security/ns1:elem)</qry:annotation>
      <qry:lower-bound xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">CTPA</qry:lower-bound>
      <qry:upper-bound xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">CTPA</qry:upper-bound>
    </qry:range-query>
      </qry:partial-plan>
      <qry:elem-word-trace text="CTPA" elem-name="elem" elem-uri="http://ns1">
    <qry:key>6185531260368494803</qry:key>
      </qry:elem-word-trace>
      <qry:info-trace>Search query contributed 1 constraint: cts:and-query((cts:path-range-query("//ns1:security/ns1:elem", "=", "CTPA", ("collation=http://marklogic.com/collation/"), 1), cts:not-query(cts:element-query(xs:QName("ns1:security"), cts:element-value-query(xs:QName("ns1:elem"), "CTPA/*", ("wildcarded","lang=en"), 1), ()), 1)), ())</qry:info-trace>
      <qry:partial-plan>
    <qry:and-not-two-queries>
      <qry:range-query weight="0" min-occurs="1" max-occurs="4294967295" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <qry:key>12785637774270294680</qry:key>
        <qry:annotation>path(//ns1:security/ns1:elem)</qry:annotation>
        <qry:lower-bound xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">CTPA</qry:lower-bound>
        <qry:upper-bound xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">CTPA</qry:upper-bound>
      </qry:range-query>
      <qry:and-two-queries>
        <qry:or-two-queries>
          <qry:term-query weight="0">
        <qry:key>17253116673510471442</qry:key>
        <qry:annotation>element(ns1:security)</qry:annotation>
          </qry:term-query>
          <qry:term-query weight="0">
        <qry:key>12929598538251878498</qry:key>
        <qry:annotation>link-child(descendant(element(ns1:security)))</qry:annotation>
          </qry:term-query>
        </qry:or-two-queries>
        <qry:term-query weight="1">
          <qry:key>6185531260368494803</qry:key>
          <qry:annotation>element(http://one.oecd.org/ns1:elem,word("CTPA"))</qry:annotation>
        </qry:term-query>
      </qry:and-two-queries>
    </qry:and-not-two-queries>
      </qry:partial-plan>
      <qry:info-trace>Executing search.</qry:info-trace>
      <qry:ordering/>
      <qry:final-plan>
    <qry:and-query>
      <qry:and-not-two-queries>
        <qry:range-query weight="0" min-occurs="1" max-occurs="4294967295" xmlns:xs="http://www.w3.org/2001/XMLSchema">
          <qry:key>12785637774270294680</qry:key>
          <qry:annotation>path(//ns1:security/ns1:elem)</qry:annotation>
          <qry:lower-bound xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">CTPA</qry:lower-bound>
          <qry:upper-bound xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">CTPA</qry:upper-bound>
        </qry:range-query>
        <qry:and-two-queries>
          <qry:or-two-queries>
        <qry:term-query weight="0">
          <qry:key>17253116673510471442</qry:key>
          <qry:annotation>element(ns1:security)</qry:annotation>
        </qry:term-query>
        <qry:term-query weight="0">
          <qry:key>12929598538251878498</qry:key>
          <qry:annotation>link-child(descendant(element(ns1:security)))</qry:annotation>
        </qry:term-query>
          </qry:or-two-queries>
          <qry:term-query weight="1">
        <qry:key>6185531260368494803</qry:key>
        <qry:annotation>element(http://one.oecd.org/ns1:elem,word("CTPA"))</qry:annotation>
          </qry:term-query>
        </qry:and-two-queries>
      </qry:and-not-two-queries>
    </qry:and-query>
      </qry:final-plan>
      <qry:info-trace>Selected 0 fragments to filter</qry:info-trace>
      <qry:result estimate="0"/>
    </qry:query-plan>
  </search:plan>
  <search:metrics>
    <search:query-resolution-time>PT0.001512S</search:query-resolution-time>
    <search:total-time>PT0.0024561S</search:total-time>
  </search:metrics>
</search:response>

0voto

Mads Hansen Points 24537

Donc, je crois que le problème est que la requête négative, cherchant à exclure les ns1:elem qui ont des valeurs commençant par CTPA/ produit une recherche de terme pour le mot CTPA . D'après le plan, nous voyons :

<qry:term-query weight="1">
  <qry:key>6185531260368494803</qry:key>                              
  <qry:annotation>element(http://one.oecd.org/ns1:elem,word("CTPA"))</qry:annotation>
</qry:term-query>

à l'intérieur de la non-requête :

<qry:and-not-two-queries>
  <qry:range-query weight="0" min-occurs="1" max-occurs="4294967295" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <qry:key>12785637774270294680</qry:key>
    <qry:annotation>path(//ns1:security/ns1:elem)</qry:annotation>
    <qry:lower-bound xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">CTPA</qry:lower-bound>
    <qry:upper-bound xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">CTPA</qry:upper-bound>
  </qry:range-query>
  <qry:and-two-queries>
    <qry:or-two-queries>
  <qry:term-query weight="0">
    <qry:key>17253116673510471442</qry:key>
    <qry:annotation>element(ns1:security)</qry:annotation>
  </qry:term-query>
  <qry:term-query weight="0">
    <qry:key>12929598538251878498</qry:key>
    <qry:annotation>link-child(descendant(element(ns1:security)))</qry:annotation>
  </qry:term-query>
    </qry:or-two-queries>
    <qry:term-query weight="1">
  <qry:key>6185531260368494803</qry:key>
  <qry:annotation>element(http://one.oecd.org/ns1:elem,word("CTPA"))</qry:annotation>
    </qry:term-query>
  </qry:and-two-queries>
</qry:and-not-two-queries>

S'il s'agissait d'une requête positive, vous obtiendriez les éléments souhaités ainsi que quelques faux positifs, qui pourraient ensuite être filtrés. Mais quand vous la niez, ces faux positifs (ceux qui ne sont que la valeur CTPA ) sont inclus dans l'ensemble à exclure, donc tout est éliminé.

Il existe des options de base de données telles que recherches de caractères génériques de fin y recherches à trois caractères qui peuvent aider à la résolution des requêtes, ainsi que d'autres options d'indexation par caractères génériques qui peuvent aider aux requêtes avec caractères génériques. Pour en savoir plus, consultez la documentation de Comprendre et utiliser les recherches par caractères génériques .

J'ai activé les deux options mentionnées ci-dessus, et j'ai transformé la requête mot en requête valeur avec l'option punctuation-sensitive y wildcarded options appliquées :

<cts:not-query>
  <cts:element-query>
    <cts:element xmlns:ns1="http://ns1">ns1:security</cts:element>
    <cts:element-value-query>
      <cts:element xmlns:ns1="http://ns1">ns1:elem</cts:element>
      <cts:text xml:lang="en">ABC/*</cts:text>
      <cts:option>wildcarded</cts:option>
      <cts:option>punctuation-sensitive</cts:option>
    </cts:element-value-query>
  </cts:element-query>
</cts:not-query>

et ensuite il a produit cette requête dans mon plan :

<qry:and-three-queries>
  <qry:term-query weight="1">
    <qry:key>11040420969293892357</qry:key>
    <qry:annotation>element(http://ns1:elem,word("ABC"))</qry:annotation>
  </qry:term-query>
  <qry:term-query weight="1">
    <qry:key>5369780126042640453</qry:key>
    <qry:annotation>word("ABC*")</qry:annotation>
  </qry:term-query>
  <qry:term-query weight="1">
    <qry:key>15274949237949545150</qry:key>
    <qry:annotation>word("*BC/*")</qry:annotation>
  </qry:term-query>
</qry:and-three-queries>

Et produit maintenant les résultats escomptés, en trouvant ceux avec ABC et non ceux qui ont ABC/* .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X