簡體   English   中英

使用 cts:not-query 或 cts:and-not-query 的問題

[英]Issue using cts:not-query or cts:and-not-query

我的 MarkLogic 版本是 9。我有 2 個查詢在單獨運行時返回預期結果,但是當我嘗試將它們組合時我沒有得到任何結果。

我的數據如下所示,我只需要匹配 ABC,而不是 ABC/*(或 ABC/D,如果這是搜索條件,在這種情況下,不是 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>

下面的代碼返回 4 個結果

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>
)

而這一項只有 3 個結果

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>
)

所以我期望在運行這個時得到 1 個結果

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>
)

我也試過這個但結果相同

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>
)

這是一個已知的錯誤? 我在這里做錯了嗎? 任何幫助表示贊賞:)

搜索計划

<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>

因此,我認為問題在於否定查詢,希望排除具有以CTPA/開頭的值的ns1:elem元素,正在為單詞CTPA生成術語查詢。 從計划中,我們看到:

<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-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>

現在,如果這是一個肯定的查詢,您將收集所需的項目以及一些誤報,然后可以將它們過濾掉。 但是當你否定它時,那些誤報(那些只是值CTPA的那些)被包含在要排除的集合中,所以一切都被消除了。

有一些數據庫選項,例如尾隨通配符搜索三字符搜索,可以幫助解決查詢問題,還有一些其他通配符索引選項可以幫助解決通配符查詢。 閱讀了解和使用通配符搜索的文檔中的更多信息。

我啟用了上面提到的這兩個選項,並將單詞查詢更改為值查詢,並應用了punctuation-sensitivewildcarded選項:

<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>

然后它在我的計划中產生了這個查詢:

<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>

現在正在產生預期的結果,找到那些有ABC而不是那些有ABC/*的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM