XQueryを使用してxmlドキュメント内の重複データを見つけるにはどうすればよいですか?
-
22-07-2019 - |
質問
MarkLogic xmlデータベースに多数のドキュメントがあります。 1つのドキュメントの内容:
<colors>
<color>red</color>
<color>red</color>
</colors>
複数の色を持つことは問題ではありません。両方が赤である複数の色を持つことは問題です。データが重複しているドキュメントを見つけるにはどうすればよいですか?
解決
MarkLogicが返すものはすべてノードのシーケンスであるため、全体のシーケンスサイズをカウントし、個別の値のシーケンスのカウントと比較できます。それらが明確でない場合、それらは重複しており、サブセットがあります。
for $c in doc()//colors
where fn:count($c/color) != fn:count(fn:distinct-values($c/color))
return $c
他のヒント
またはインデックスから完全にそれを行うことができます:)
doc()// colorsの$ c
では、より大きなデータセットで EXPANDED TREE CACHE エラーが発生する可能性があります。
これは、データが巨大な場合にこれを攻撃するためのもう少し複雑な方法です。 URI辞書がオンになっていることを確認してから、要素範囲インデックスを要素 color を作成し、重複するどこかの異なる色の値を計算します。次に、この色を持つドキュメントのみを1つずつループ処理し、ドキュメント内の目的の色のアイテム頻度カウントを計算します。頻度が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
役立つこと。
この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 > 1">
<xsl:text>Color value of </xsl:text><xsl:value-of select="."/><xsl:text> has multiple entries 
</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
これにより、少なくともそれらは検出されますが、繰り返されるすべての色だけでなく、繰り返される色の各出現が報告されます。
これでうまくいくはずです。私はMarkLogicにあまり詳しくないので、一連のドキュメントを取得する最初の行が間違っている可能性があります。これにより、同じ文字列値を持つ2つ以上の色要素を持つすべてのドキュメントが返されます。
for $doc in doc()
let $colors = $doc//color/string(.)
where some $color in $colors
satisfies count($colors[. = $color] > 1)
return doc()