Wie finde ich doppelte Daten in XML-Dokument XQuery verwenden?
-
22-07-2019 - |
Frage
Ich habe eine Reihe von Dokumenten in einer XML-Datenbank Marklogic. Ein Dokument hat:
<colors>
<color>red</color>
<color>red</color>
</colors>
mehr Farben zu haben, ist das kein Problem. mehrere Farben aufweist, die beide rot sind, ist ein Problem. Wie kann ich die Dokumente finden, die doppelten Daten haben?
Lösung
Alles Marklogic gibt nur eine Folge von Knoten ist, so können wir die Reihenfolge Größe der gesamten zählen und auf die Zählung der Folge von unterschiedlichen Werten vergleichen. Wenn sie nicht unterscheidbar sind, sind sie doppelt, und Sie haben Ihre Teilmenge.
for $c in doc()//colors
where fn:count($c/color) != fn:count(fn:distinct-values($c/color))
return $c
Andere Tipps
Oder Sie könnten es vollständig tun aus Indizes:)
for $c in doc()//colors
ist wahrscheinlich ein AUSGEBAUT TREE CACHE Fehler auf größere Datensätze erstellen.
Hier ist ein etwas komplizierter Weg, dies zu attackieren, wenn die Daten sehr groß sind, stellen Sie sicher, dass der URI Lexikon eingeschaltet und dann -Element Entfernungs-Index auf dem hinzufügen Element Farbe und berechnen die unterschiedlichen Farbwerte, die Duplizierung irgendwo haben. Dann Schleife über nur die Dokumente, die diese Farbe eines nach dem anderen haben und berechnen die item-Frequenzzählungen der Farben von Interesse in den Dokumenten. Wenn Sie eine Frequenz über 1 bekommen, dieses Dokument muss Deduplizierung.
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
Ich hoffe, das hilft.
Für diese XML:
<?xml version="1.0"?>
<colors>
<color>Red</color>
<color>Red</color>
<color>Blue</color>
</colors>
Mit dieser 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>
Ich habe diese Ausgabe:
Color value of Red has multiple entries
Color value of Red has multiple entries
Damit wird sie zumindest finden, aber es wird jedes Auftreten einer wiederholten Farbe berichten, nicht nur jede wiederholte Farbe.
Dies sollte den Trick tun. Ich bin nicht allzu vertraut mit Marklogic, so die erste Zeile aus den Unterlagen zu bekommen kann falsch sein. Dadurch werden alle Dokumente zurück, die 2 oder mehr Farbelemente mit dem gleichen String-Wert.
for $doc in doc()
let $colors = $doc//color/string(.)
where some $color in $colors
satisfies count($colors[. = $color] > 1)
return doc()