如何使用XQuery在xml文档中找到重复数据?

时间:2009-01-15 01:01:22

标签: xml xquery duplicate-data marklogic

我在MarkLogic xml数据库中有很多文档。一份文件有:

<colors>
  <color>red</color>
  <color>red</color>
</colors>

拥有多种颜色不是问题。多种颜色都是红色是一个问题。如何查找具有重复数据的文档?

4 个答案:

答案 0 :(得分:2)

或者你可以完全用索引完成:)

for $c in doc()//colors可能会在较大的数据集上创建 EXPANDED TREE CACHE 错误。

当数据很大时,这是一种稍微复杂的攻击方式,确保打开 URI Lexicon 然后在其上添加元素范围索引元素颜色并计算具有重复某处的不同颜色值。然后仅逐个循环具有此颜色的文档,并计算文档中感兴趣的颜色的项目频率计数。如果频率超过1,则本文档需要重复数据删除。

let $qn := xs:QName("color")
let $colorsWithItemFreq := cts:element-values($qn, (), ("ascending", "item-order", "item-frequency"))
let $colorsOfInterest := 
    for $color at $i in cts:element-values($qn, (), ("ascending", "item-order", "fragment-frequency"))
    let $fragFrequency := cts:frequency($color)
    let $itemFrequency := cts:frequency($colorsWithItemFreq[$i])
    where $itemFrequency gt $fragFrequency
    return 
        $color

for $uri in cts:uris( (), ("document"), cts:element-value-query($qn, $colorsOfInterest)
let $colorsWithDuplicationInThisDoc :=
    for $color in cts:element-values($qn, (), ("item-frequency"), cts:document-query($uri) )
    where $color = $colorsOfInterest and cts:frequency($color) gt 1
    return
        $color
where fn:count( $colorsWithDuplicationInThisDoc ) gt 1
return
    $uri

希望有所帮助。

答案 1 :(得分:1)

这应该可以解决问题。我对MarkLogic不太熟悉,因此获取这组文档的第一行可能是错误的。这将返回具有2个或更多具有相同字符串值的颜色元素的所有文档。

for $doc in doc()
let $colors = $doc//color/string(.)
where some $color in $colors
      satisfies count($colors[. = $color] > 1)
return doc()

答案 2 :(得分:1)

对于这个XML:

<?xml version="1.0"?>
<colors>
    <color>Red</color>
    <color>Red</color>
    <color>Blue</color>
</colors>

使用此XSD:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method = "text" />  
    <xsl:strip-space elements="*"/>

    <xsl:template match="colors">

        <xsl:for-each select="color">
            <xsl:variable name="node_color" select="text()"/>
            <xsl:variable name="numEntries" select="count(../color[text()=$node_color])"/>
            <xsl:if test="$numEntries &gt; 1">
                <xsl:text>Color value of </xsl:text><xsl:value-of select="."/><xsl:text> has multiple entries &#xa;</xsl:text>      
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

我得到了这个输出:

Color value of Red has multiple entries 
Color value of Red has multiple entries 

所以至少会找到它们,但它会报告重复颜色的每次出现,而不仅仅是每个重复的颜色。

答案 3 :(得分:1)

MarkLogic返回的所有内容只是一个节点序列,因此我们可以计算整个序列的大小,并将其与不同值序列的计数进行比较。如果它们不是截然不同的,那么它们就是重复的,并且你有你的子集。

for $c in doc()//colors
where fn:count($c/color) != fn:count(fn:distinct-values($c/color))
return $c