跳至內容

XQuery/檔案大小直方圖

來自華夏公益教科書

您在一個或多個集合中擁有大量檔案,您希望生成一個直方圖圖表,顯示每個大小範圍內的檔案數量的相對分佈。

我們將使用 xmldb:size() 函式來生成給定集合中所有檔案大小的列表。然後,我們可以將此列表轉換為一系列字串,這些字串可以傳遞到 Google Charts 線形圖函式。

size 函式的格式如下

 xmldb:size($collection, $document-name)

此函式返回檔案中的位元組數。


我們的第一步是建立一個數字序列,代表集合中所有資源的大小

 let $sizes :=
  for $file in xmldb:get-child-resources($collection)
     let $size := xmldb:size($collection, $file)
     return
        $size

這也可以透過組合 collection() 函式和 util:document-name() 函式來完成

  let $sizes :=
     for $file in collection($collection)/*
        let $name := util:document-name($file)
        let $size := xmldb:size($collection, $name)
        return
           $size

示例程式

[編輯 | 編輯原始碼]
xquery version "1.0";

declare option exist:serialize "method=xhtml media-type=text/html";

(: Put the collection you want to analyze here :)
let $collection := "/db/test"

(: How many bytes in each section :)
let $increment := 10000

(: How many divisions :)
let $divisions := 20

(: Color for the lines or the bars in RRGGBB :)
let $color := '0000FF'

(: For vertical bar chart use 'bvs', for line chart use 'lc', for spark line (no axis) use 'ls' :)
let $chart-type := 'bvs'

(: this is the max size of a google chart - 30K pixels.  The first number is the width, the second is the height.  :)
let $chart-size := '600x500'

let $uriapi := 'http://chart.apis.google.com/chart?'

let $sizes :=
   for $file in xmldb:get-child-resources($collection)
      let $size := xmldb:size($collection, $file)
      return
         $size

(: the raw data counts for each range.  The 't' is just a marker that it is true that we are in this range. :)
let $raw-data :=
    for $range in (0 to $divisions)
       let $min := $range * $increment
       let $max := ($range + 1) * $increment
       return
          count(
               for $number in $sizes
               return
                 if ($number gt $min and $number lt $max)
                 then ('t') else ()
              )

let $max-value := max($raw-data)

(: scale to the max height :)
let $scaled-data := 
   for $num in $raw-data
   return string(floor($num div ($max-value div 500)))

(: join the strings with commas to get a comma separated list :)
let $data-csv := string-join($scaled-data, ',')

(: construct the URL :)
let $chart-uri := concat($uriapi, 'cht=', $chart-type, '&chs=', $chart-size, '&chco=', $color, '&chd=t:', $data-csv)

(: return the results in an HTML page :)
<html>
<head><title>Google Chart Histogram View of {$collection}</title></head>
<body>
<h1>Google Chart Histogram View of {$collection}</h1>
<p><img src="{request:encode-url(xs:anyURI($chart-uri))}"/></p>
</body>
</html>

示例結果

[編輯 | 編輯原始碼]

http://chart.apis.google.com/chart?cht=ls&chs=500x500&chco=0000FF&chd=t:83,6,13,37,85,414,500,87,41,31,11,16,9,12,5,7,4,4,3,1,1

要執行查詢,您需要自定義要分析的集合的名稱。執行查詢後,您可以檢查結果是否符合預期,然後將結果複製到瀏覽器 URL 中。

請注意,如果存在超過最高範圍內指示的最大大小的檔案,則應新增這些檔案大小的額外計數。

 let $top-range := $increment * ($divisions + 1)
 let $top-count := count(
           for $num in $sizes
           return
              if ($num > $overflow)
                then ('t')
                else ()
       )

此查詢也可以使用 get-parameter() 函式進行引數化,以便傳遞到 Google 圖表的許多引數也可以在 URL 的 XQuery 中作為引數設定。

華夏公益教科書