Pregunta

Tengo un montón de documentos en una base de datos xml de MarkLogic. Un documento tiene:

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

Tener múltiples colores no es un problema. Tener múltiples colores que son rojos es un problema. ¿Cómo encuentro los documentos que tienen datos duplicados?

¿Fue útil?

Solución

Todo lo que MarkLogic devuelve es solo una secuencia de nodos, por lo que podemos contar el tamaño de secuencia del conjunto y compararlo con el recuento de la secuencia de valores distintos. Si no son distintos, están duplicados y tiene su subconjunto.

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

Otros consejos

O podrías hacerlo completamente fuera de los índices :)

para $ c en doc () // colores es probable que cree un error CACHE DE ÁRBOL AMPLIADO en conjuntos de datos más grandes.

Aquí hay una forma un poco más complicada de atacar esto cuando los datos son enormes, asegúrese de que el URI Lexicon esté activado y luego agregue un índice de rango de elementos en el elemento color y calcule los distintos valores de color que tienen duplicación en alguna parte . Luego, repita solo los documentos que tienen este color uno por uno y calcule los recuentos de frecuencia de elementos de los colores de interés en los documentos. Si obtiene una frecuencia superior a 1, este documento necesita desduplicación.

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

Espero que eso ayude.

Para este XML:

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

Uso de este 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>

Obtuve esta salida:

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

Así que al menos los encontrará, pero informará cada aparición de un color repetido, no solo cada color repetido.

Esto debería hacer el truco. No estoy muy familiarizado con MarkLogic, por lo que la primera línea para obtener el conjunto de documentos puede estar equivocada. Esto devolverá todos los documentos que tengan 2 o más elementos de color con el mismo valor de cadena.

for $doc in doc()
let $colors = $doc//color/string(.)
where some $color in $colors
      satisfies count($colors[. = $color] > 1)
return doc()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top