2009-01-15 17 views

Répondre

1

Tout ce que MarkLogic renvoie est juste une séquence de nœuds, donc nous pouvons compter la taille de séquence de l'ensemble et le comparer au nombre de séquences de valeurs distinctes. S'ils ne sont pas distincts, ils sont en double et vous avez votre sous-ensemble.

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

En fonction de vos besoins de mise à l'échelle, la mémoire sera rapidement épuisée. Voir l'approche index seulement ci-dessous – derickson

1

Cela devrait faire l'affaire. Je ne connais pas très bien MarkLogic, donc la première ligne pour obtenir l'ensemble des documents peut être erronée. Cela retournera tous les documents qui ont 2 éléments de couleur ou plus avec la même valeur de chaîne.

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

L'itération sur tous les documents est-elle la seule solution? – Sixty4Bit

1

Pour ce XML:

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

En utilisant cette 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> 

Je suis cette sortie:

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

Donc, ça va au moins trouver eux, mais il rapportera chaque occurrence d'une couleur répétée, pas seulement chaque couleur répétée.

2

Ou vous pourriez le faire complètement hors d'index :)

for $c in doc()//colors est susceptible de créer un ETENDUE TREE CACHE erreur sur des ensembles de données plus importants.

Voici une façon un peu plus compliqué d'attaquer quand les données est énorme, assurez-vous que l'URI Lexicon est activée, puis ajoutez un indice de gamme d'éléments sur l'élément couleur et calculer la couleur distincte valeurs qui ont la duplication quelque part. Ensuite, bouclez seulement les documents qui ont cette couleur un par un et calculez les nombres d'éléments-fréquences des couleurs d'intérêt dans les documents. Si vous obtenez une fréquence supérieure à 1, ce document doit être dédupliqué.

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 

Espérons que cela aide.