2

我的 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>
4

1 回答 1

0

所以,我认为问题在于否定查询,希望排除ns1:elem具有以开头的值的元素,CTPA/正在为 word 生成一个 term-query 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>

现在,如果这是一个肯定的查询,您将收集所需的项目以及一些误报,然后可以将它们过滤掉。但是当你否定它时,那些误报(那些只是 value 的那些CTPA)被包含在要排除的集合中,所以一切都被消除了。

有一些数据库选项,例如尾随通配符搜索三字符搜索,可以帮助解决查询,还有一些其他通配符索引选项可以帮助解决通配符查询。阅读了解和使用通配符搜索的文档中的更多信息。

我启用了上面提到的两个选项,并将 word-query 更改为 value-query 并应用了punctuation-sensitiveandwildcarded选项:

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

于 2021-12-02T15:10:21.547 回答