首页 > 解决方案 > Marklogic XQuery 根据条件删除元素块

问题描述

我在 Marklogic 数据库中有一个文档,并希望使用 XQuery 保留评级代码为“同意”或“强烈同意”的产品节点,其他节点需要删除。

我尝试了几个选项来找到具有适当属性的节点并删除其他节点,但没有运气之类的

让 $rating5Exists := fn:exists($doc//rating[@code eq "Strongly Agree"])

让 $rating4Exists := fn:exists($doc//rating[@code eq "Agree"])

<products>
    <product>
        <product-id>9039034</product-id>
        <status>
            <rating code="Strongly Agree">
                <count>5</count>
            </rating>
        </status>
    </product>
    <product>
        <product-id>9039034</product-id>
        <status>
            <rating code="Agree">
                <count>4</count>
            </rating>
        </status>
    </product>
    <product>
        <product-id>9039034</product-id>
        <status>
            <rating code="Neither Agree nor Disagree">
                <count>3</count>
            </rating>
        </status>
    </product>
    <product>
        <product-id>9039034</product-id>
        <status>
            <rating code="Disagree">
                <count>2</count>
            </rating>
        </status>
    </product>
    <product>
        <product-id>9039034</product-id>
        <status>
            <rating code="Strongly Disagree">
                <count>1</count>
            </rating>
        </status>
    </product>
</products>

预期输出:

<products>
    <product>
        <product-id>9039034</product-id>
        <status>
            <rating code="Strongly Agree">
                <count>5</count>
            </rating>
        </status>
    </product>
    <product>
        <product-id>9039034</product-id>
        <status>
            <rating code="Agree">
                <count>4</count>
            </rating>
        </status>
    </product>
</products>

标签: xquerymarklogic-8

解决方案


在 MarkLogic 中有几种方法可以做到这一点。一般而言,它归结为在现场操作文档、使用节点更新语句或重写整个文档。任何一种方法的性能都可以很好。

节点更新方法(在 XQuery 中)可能如下所示:

for $product in
    $doc/products/product
let $rating :=
    $product/status/rating
where
    not($rating/@code = ('Agree', 'Strongly Agree'))
return
    xdmp:node-delete($product)

文档重写方法(在 XQuery 中)可能如下所示:

let $newDoc := element { node-name($doc/*) } {
    $doc/*/namespace::*,
    $doc/*/@*,
    $doc/*/product[status/rating/@code = ('Agree', 'Strongly Agree')]
}
return
    (: using node-replace here to preserve doc permissions, collections, etc :)
    xdmp:node-replace($doc, $newDoc)


推荐阅读