跳至內容

XQuery/限制結果集

來自華夏公益教科書

有時您在集合中有很多記錄或例項,並且希望限制查詢返回的資料量。

限制文件中的記錄

[編輯 | 編輯原始碼]

如果您要限制大型 XML 文件中的記錄,可以透過在 for 迴圈的末尾新增謂詞來實現。

  for $person in doc($file)/Person[position() lt 10]

使用子序列限制結果

[編輯 | 編輯原始碼]

以下查詢僅檢索集合中按順序包含的前 10 個文件。

  for $person in subsequence(collection($my-collection)/person, 1, 10)

其中

  subsequence($sequence, $starting-item, $number-of-items)

請注意,第二個引數是起始項,第三個引數是要返回的總項數。它不是要返回的最後一項。

在限制結果之前排序

[編輯 | 編輯原始碼]

請注意,通常您希望根據某些排序條件獲取前 N 個文件,例如姓氏以字母“A”開頭的使用者。因此,您需要做的第一件事是建立具有正確順序的節點列表,然後從該列表中獲取前 N 個記錄。這通常可以透過建立作為單獨 FLWOR 表示式的已排序專案的臨時序列來完成。

let $sorted-people :=
   for $person in collection($collection)/person
   order by $person/last-name/text()
   return $person

for $person at $count in subsequence($sorted-people, $start, $number-of-records)
return
   <li>$person/last-name/text()</li>

新增按鈕以獲取下一個 N 個記錄

[編輯 | 編輯原始碼]

獲取下一個 N 行

[編輯 | 編輯原始碼]

從序列中獲取前 N 項後,您經常希望獲取下一個 N 行。為此,您需要在報表中新增“上一個 N 個記錄”和“下一個 N 個記錄”按鈕。這些按鈕將向您的 XQuery 傳遞引數,告訴它從哪裡開始以及要獲取多少條記錄。

為此,您需要使用 URL 中的不同引數呼叫您自己的指令碼。為了跟蹤 URL,您可以使用 eXist 附帶的 get-url() 函式。例如

  let $query-base := request:get-url()

如果您的查詢是從 http:/localhost:8080/exist/rest/db/apps/user-manager/views/list-people.xq 執行的,則返回的字串將是。

我們還將從 URL 中獲取兩個引數,用於要開始的記錄以及要獲取的記錄數

  let $start := xs:integer(request:get-parameter("start", "1"))
  let $num := xs:integer(request:get-parameter("num", "20"))

現在,我們將建立兩個 HTML 按鈕,使我們能夠獲取下一個 N 個記錄或上一個 N 個記錄。

   <input type="button" onClick="parent.location='{$query-base}?start={$start - $num}&amp;num={$num}'" value="&lt; Previous"/>
   <input type="button" onClick="parent.location='{$query-base}?start={$start + $num}&amp;num={$num}'" value="Next &gt;"/>

完整示例程式

[編輯 | 編輯原始碼]
xquery version "1.0";
declare namespace u="http://niem.gov/niem/universal/1.0";

let $start := xs:integer(request:get-parameter("start", "1"))
let $num := xs:integer(request:get-parameter("num", "5"))
let $query-base := request:get-url()

return
<html>
   <title>Contacts</title> 
   <body>
      <h1>Contacts</h1>
      <table border="1">
         <thead>
            <tr>
               <th>ID</th>
               <th>Last Name</th>
               <th>First</th>
               <th>Street</th>
               <th>City</th>
               <th>State</th>
               <th>Zip</th>
               <th>EMail</th>
               <th>Phone</th>
               <th colspan="2">Function</th>
            </tr>
          </thead>
      <tbody>
      {
      for $person in subsequence(collection('/db/contacts/data/')//Person, $start, $num)
        let $pid := $person/id
        let $lname := $person/u:PersonSurName/text()
        let $fname := $person/u:PersonGivenName/text()
        let $street := $person/u:StreetFullText/text()
        let $city := $person/u:LocationCityName/text()
        let $state := $person/u:LocationStateName/text()
        let $zip := $person/u:LocationPostalCodeID/text()
        let $email := $person/u:ContactEmailID/text()
        let $phone := $person/u:TelephoneNumberFullID/text()
        order by $lname, $fname
        return
        <tr>
           <td>{$pid}</td>
           <td>{$lname}</td>
           <td>{$fname}</td>
           <td>{$street}</td>
           <td>{$city}</td>
           <td>{$state}</td>
           <td>{$zip}</td>
           <td>{$email}</td>
           <td>{$phone}</td>
        </tr>
      }
      </tbody>
    </table>
    <input type="button"
       onClick="parent.location='{$query-base}?start={$start - $num}&amp;num={$num}'" value="&lt; Previous"/>
    <input type="button"
       onClick="parent.location='{$query-base}?start={$start + $num}&amp;num={$num}'" value="Next &gt;"/>
  </body>
</html>
華夏公益教科書