![](/img/trans.png)
[英]How to combine cts:search searchable-expression and cts: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(<map:map xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" .../>), "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-sensitive
和wildcarded
選項:
<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.