كيف يمكنني العثور على بيانات مكررة في مستند xml باستخدام XQuery?

StackOverflow https://stackoverflow.com/questions/445281

سؤال

لدي مجموعة من الوثائق في MarkLogic قاعدة بيانات xml.واحدة الوثيقة:

<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

نصائح أخرى

أو يمكنك أن تفعل ذلك تماما من الفهارس :)

for $c in doc()//colors من المرجح أن تخلق توسيع شجرة ذاكرة التخزين المؤقت خطأ على أكبر مجموعات البيانات.

هنا هو قليلا أكثر تعقيدا من طريقة هذا الهجوم عندما تكون البيانات الضخمة ، تأكد أوري المعجم تشغيل ثم إضافة عنصر مجموعة مؤشر على عنصر اللون وحساب متميزة قيم الألوان التي الازدواجية في مكان ما.ثم حلقة فقط الوثائق التي لديها هذه الألوان واحدا تلو الآخر وحساب البند-تردد التهم من ألوان الفائدة في الوثائق.إذا كنت تحصل على تردد أكثر من 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 &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>

وحصلت على هذا الإخراج:

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()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top