Marklogic 在XQuery中使用多个Order By参数动态排序
我想按多个属性对文档进行排序,这些属性在MarkLogic 8中可能是范围索引,也可能不是范围索引 理想情况下,我会有一个XQuery函数,它将接受一系列节点、一系列属性作为字符串进行排序,以及一系列方向作为字符串进行排序 我通过一个Marklogic 在XQuery中使用多个Order By参数动态排序,marklogic,marklogic-8,Marklogic,Marklogic 8,我想按多个属性对文档进行排序,这些属性在MarkLogic 8中可能是范围索引,也可能不是范围索引 理想情况下,我会有一个XQuery函数,它将接受一系列节点、一系列属性作为字符串进行排序,以及一系列方向作为字符串进行排序 我通过一个xdmp:value调用完成了这一点,请参见下文。然而,这很容易受到注射的影响。是否有人能够使用xdmp:unpath或xdmp:invoke或完全不同的解决方案来帮助解决问题 xquery version "1.0-ml"; declare function l
xdmp:value
调用完成了这一点,请参见下文。然而,这很容易受到注射的影响。是否有人能够使用xdmp:unpath
或xdmp:invoke
或完全不同的解决方案来帮助解决问题
xquery version "1.0-ml";
declare function local:sort-dynamically(
$nodes as node()*,
$sortbys as xs:string*,
$directions as xs:string*
) as node()*
{
(: build the components for the order by string
model: order by node//property direction
:)
let $order-bys :=
for $i in 1 to count($sortbys)
return
"$node//" || $sortbys[$i] || " " || $directions[$i]
(: join the order bys, separated by comma + space :)
let $order-bys-string := fn:string-join($order-bys, ", ") || " "
(: create the eval string
model: for node in nodes
order by
node//property1 direction1, node//property2 direction2
return
node
:)
let $eval-string :=
fn:concat(
"for $node in $nodes ",
"order by ",
$order-bys-string,
"return $node"
)
(: evaluate the sort :)
return
xdmp:value(
$eval-string
)
};
let $nodes := (
xdmp:unquote('{"col1": "1", "col2": "a"}'),
xdmp:unquote('{"col1": "1", "col2": "a"}'),
xdmp:unquote('{"col1": "1", "col2": "b"}'),
xdmp:unquote('{"col1": "2", "col2": "a"}')
)
let $sortbys := ("col1", "col2")
let $directions := ("ascending", "descending")
return
local:sort-dynamically($nodes, $sortbys, $directions)
如果可以使用and,您会有更大的灵活性,但这似乎不是一个选项,因为您希望传递一系列节点(可能像在您的示例中那样在内存中构造),并且可能没有针对所有排序键的范围索引 请记住,使用
cts:order
进行cts:search
将提供最佳排序性能
总而言之,这让你几乎没有选择。使用xdmp:value
可以被视为一种安全风险,但您可以通过严格的输入验证来抵消这种风险。您可以使用$sortbys作为xs:QName+
,而不是使用$sortbys作为xs:string*
。您可以使用$升序作为xs:boolean+
(以及一些代码调整),而不是将$方向作为xs:string*
。这将使代码注入变得不可能
嗯