跳至内容

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>
华夏公益教科书