MarkLogic版本:8.0-3.2
如果在搜索:搜索选项节点(如<element xmlns:bar="myuri:baz" xmlns:foo="myuri:baz">
)中有一个具有不同前缀但具有相同URI的多个名称空间声明,则除了第一个前缀之外的每个前缀都会在搜索:搜索调用中丢失。
这是预期的行为吗?它在ML7.0-4.3下不存在,我不知道在不同前缀下的同一名称空间uri的多个声明违反了XML命名空间或xQuery规范。
非常感谢任何见解。
(:~
: Two transactions:
: (1) Create an element range index on element {myuri:baz}child in "Documents" database
: (2) Insert a test document at /baz/test/test-baz.xml
:
: Expected output: empty sequence
:)
(: Transaction (1): Set up index :)
xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration(),
$dbid := xdmp:database("Documents"),
$rangespec := admin:database-range-element-index("string", "myuri:baz", "child", "http://marklogic.com/collation/", fn:false(), "reject")
return
try {
admin:save-configuration-without-restart(
admin:database-add-range-element-index($config, $dbid, $rangespec)
)
} catch($e) {
"Index already exists? Check logs.",
xdmp:log($e, "debug")
}
;
(: Transaction (2): Insert test document :)
xquery version "1.0-ml";
declare namespace baz = "myuri:baz";
let $uri := "/baz/test/test-baz.xml",
$document :=
<baz:root>
<baz:child>TEST</baz:child>
</baz:root>
return
xdmp:document-insert($uri, $document)
xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
(: additional-query: xmlns:foo first, xmlns:bar second; cts:element: foo:child. Succeeds. :)
declare variable $search-options-1 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:foo="myuri:baz" xmlns:bar="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>foo:child</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
(: additional-query: xmlns:foo first, xmlns:bar second; cts:element: bar:child. Fails. :)
declare variable $search-options-2 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:foo="myuri:baz" xmlns:bar="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>bar:child</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
(: additional-query: xmlns:bar first, xmlns:foo second; cts:element: bar:child. Succeeds. :)
declare variable $search-options-3 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:bar="myuri:baz" xmlns:foo="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>bar:child</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
(: additional-query: xmlns:bar first, xmlns:foo second; cts:element: foo:child. Fails. :)
declare variable $search-options-4 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:bar="myuri:baz" xmlns:foo="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>foo:child</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
for $search-options in ($search-options-1, $search-options-2, $search-options-3, $search-options-4)
return
try {
let $test := search:search("", $search-options, 1) instance of element(search:response)
return
if ($test) then "PASS"
else "FAIL" (: won't reach :)
} catch($e) {
$e/error:format-string/fn:string(.)
}
PASS
XDMP-ELEMRIDXNOTFOUND:cts:search(fn:collection(),cts:and-query(cts:element-range-query(xs:QName(“bar:child”),“=”,“TEST”, (“collation = http://marklogic.com/collation/”),1),()),(“score-logtfidf”,cts:score-order(“descending”)),xs:double(“1”),()) - 子http://marklogic.com/collation/
没有字符串元素范围索引PASS
XDMP-ELEMRIDXNOTFOUND:cts:search(fn:collection(),cts:and-query(cts:element-range-query(xs:QName(“foo:child”),“=”,“TEST”, (“collation = http://marklogic.com/collation/”),1),()),(“score-logtfidf”,cts:score-order(“descending”)),xs:double(“1”),()) - 子http://marklogic.com/collation/
没有字符串元素范围索引当任何祖先多次在不同的前缀下声明相同的URI时,前缀在self :: *中丢失:
xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
(: Serialize namespace w/ fn:QName(), no namespace inheritance: PASS :)
declare variable $search-options-1 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query>
<cts:element-range-query operator="=">
<cts:element>{fn:QName("myuri:baz", "child")}</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
(: Serialize namespace w/ fn:QName(), namespace inheritance, declared once: PASS :)
declare variable $search-options-2 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:foo="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>{fn:QName("myuri:baz", "child")}</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
(: Serialize namespace w/ fn:QName(), namespace inheritance, declared twice: FAIL :)
declare variable $search-options-3 :=
<options xmlns="http://marklogic.com/appservices/search">
<additional-query xmlns:foo="myuri:baz" xmlns:bar="myuri:baz">
<cts:element-range-query operator="=">
<cts:element>{fn:QName("myuri:baz", "child")}</cts:element>
<cts:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</cts:value>
</cts:element-range-query>
</additional-query>
</options>;
for $search-options in ($search-options-1, $search-options-2, $search-options-3)
return
try {
let $test := search:search("", $search-options, 1) instance of element(search:response)
return
if ($test) then "PASS"
else "FAIL" (: won't reach :)
} catch($e) {
$e/error:format-string/fn:string(.)
}
PASS
PASS
PASS
PASS
PASS
XDMP-ELEMRIDXNOTFOUND:cts:search(fn:collection(),cts:and-query(cts:element-range-query(xs:QName(“bar:child”),“=”,“TEST”, (“collation = http://marklogic.com/collation/”),1),()),(“score-logtfidf”,cts:score-order(“descending”)),xs:double(“1”),()) - 子http://marklogic.com/collation/
没有字符串元素范围索引答案 0 :(得分:3)
如果您在XQuery上下文中直接使用Search API,则可以使用fn:QName()
来获取元素QName的一致序列化:
<cts:element>{ fn:QName("myuri:baz", "child") }</cts:element>
评估为:
<cts:element xmlns:_1="myuri:baz">_1:child</cts:element>
或者,xs:QName()
将使用可用的范围内前缀:
declare namespace foo ="myuri:baz";
<cts:element>{ xs:QName("foo:child") }</cts:element>
评估为:
<cts:element xmlns:foo="myuri:baz">foo:child</cts:element>
当然,如果您将REST API与存储的搜索选项一起使用,这种方法将无济于事。
答案 1 :(得分:0)
我相信Search API一直有此限制。我同意这个意外是不幸的 - 标准并不支持这个限制 - 但是你是否很难通过为每个命名空间uri使用一个且只有一个前缀来解决限制?如果不出意外,这会使声明变得更简单。