كيف يمكنني العثور على بيانات مكررة في مستند xml باستخدام XQuery?
-
22-07-2019 - |
سؤال
لدي مجموعة من الوثائق في 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 > 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>
وحصلت على هذا الإخراج:
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()