Domanda

Ho un sacco di documenti in un database XML MarkLogic. Un documento ha:

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

Avere più colori non è un problema. Avere più colori che sono entrambi rossi è un problema. Come trovo i documenti che contengono dati duplicati?

È stato utile?

Soluzione

Tutto ciò che MarkLogic restituisce è solo una sequenza di nodi, quindi possiamo contare la dimensione della sequenza dell'insieme e confrontarla con il conteggio della sequenza di valori distinti. Se non sono distinti, sono duplicati e hai il tuo sottoinsieme.

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

Altri suggerimenti

Oppure potresti farlo completamente fuori dagli indici :)

per $ c in doc () // colors probabilmente creerà un errore CACHE ALBERO ESPANSO su set di dati più grandi.

Ecco un modo leggermente più complicato per attaccare questo quando i dati sono enormi, assicurati che URI Lexicon sia attivato e quindi aggiungi un indice di intervallo di elementi sul elemento colore e calcola i valori di colore distinti che hanno la duplicazione da qualche parte . Quindi passare in rassegna solo i documenti che hanno questo colore uno per uno e calcolare i conteggi di frequenza degli articoli dei colori di interesse nei documenti. Se ottieni una frequenza superiore a 1, questo documento necessita di deduplicazione.

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

Spero che sia d'aiuto.

Per questo XML:

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

Utilizzando questo 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>

Ho ottenuto questo output:

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

In modo che almeno li trovino, ma riporterà ogni ricorrenza di un colore ripetuto, non solo ogni colore ripetuto.

Questo dovrebbe fare il trucco. Non conosco troppo MarkLogic, quindi la prima riga per ottenere il set di documenti potrebbe essere errata. Ciò restituirà tutti i documenti che hanno 2 o più elementi di colore con lo stesso valore di stringa.

for $doc in doc()
let $colors = $doc//color/string(.)
where some $color in $colors
      satisfies count($colors[. = $color] > 1)
return doc()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top