[xquery-talk] paging mechanism

Philippe Michiels philippe.michiels at gmail.com
Fri Feb 3 11:49:08 PST 2006


Your first problem:

  for $x at $pos in 
    for $y in $doc/body/idno
    order by xs:decimal($x) ascending 
    return $y
  where ($pos mod 50) < 2
  return $x

The casting is kind of important, otherwise you may risk getting lexicographic 
ordering, when the numbers don't have leading zeros. Also, you must use the 
for-loop position binding.

The second problem should then solve itself, but don't for get to use the 
ordered version of the input there. It may be a good idea to sort the input 
first and put it in a variable.

Does that make sense?
-Ph

On Friday 03 February 2006 11:09, Peter Mueller wrote:
> Hi everybody,
>
> here is what I am trying to achieve ...
>
> I would like to implement a paging mechanism that offers access to several
> collections with between 500 and 3000 documents.
>
> When the web user selects one collection he should be presented with some
> kind of sub folder hierarchy where each "sub folder" contains "chunks" of -
> lets say 50 - documents. These "sub folders" should be labeled with the
> time period they belong to (to allow the user more specific access), e.g.:
> 1980-1983
> 1983-1986
> 1986-1987
> and so on...
> (PROBLEM 1!)
>
> If a user then chooses one time interval (lets say "1980-1983") he should
> be given a navigating structure (like [1-10] [11-20] ... [41-50]) (trivial
> if PROBLEM 2 is solved --> see below) along with some metadata of the first
> 10 "hits" (PROBLEM 2!).
>
>
> PROBLEM 1:
> For solving the first problem I need to first sort the documents (by date)
> and then extract the years from which the 1st, the 50th, the 51st and so on
> documents originate.
>
> For this tried a couple of queries (see below) which unfortunatelly didn't
> yield the expected results (using SAXON).
>
> I tested my query on just one xml file which contains 147 test-documents.
>
> [I used <idno> instead of <date> for sorting and as result because it's
> easier for testing.]
>
> for $doc in //text
> order by $doc/body/idno
> ascending return
> if($doc[(position() mod 50) < 2])then
> (
> $doc/body/idno
> )
> else()
>
> Instead of the expected:
> <idno>001</idno>
> <idno>050</idno>
> <idno>051</idno>
> <idno>100</idno>
> <idno>101</idno>
>
> ... I got the idno of all the docs:
> <idno>001</idno>
> <idno>002</idno>
> <idno>003</idno>
> ...
> <idno>147</idno>
>
>
> The same happended when I replaced the line
> if($doc[(position() mod 50) < 2])then
> with
> if((position() mod 50) < 2)then
>
> Finally, I tried:
>
> for $id at $pos in //text/body/idno
> order by xs:integer($id) ascending
> return
> if ($id[$pos mod 50 < 2]) then $id
> else ()
>
> leaving me with:
>
> <idno>012</idno>
> <idno>047</idno>
> <idno>059</idno>
> <idno>117</idno>
> <idno>123</idno>
>
> Do you have any suggestions as to how this could work correctly?
>
>
>
> PROBLEM 2:
> For solving the second problem I would need the same sorting as above and
> then extract some metadata from the documents at position number 1 to 10
> (11-20, etc...) in the resulting sequence.
>
> To solve this I tried:
>
> declare variable $startIndex as xs:integer := 1;
> declare variable $pageSize as xs:integer := 10;
> for $idno in
> fn:subsequence( //text/body/idno, $startIndex, $pageSize)
> order by $idno
> return $idno
>
> instead of the expected:
> <idno>001</idno>
> <idno>002</idno>
> <idno>003</idno>
> ...
> <idno>010</idno>
>
> I got:
> <idno>001</idno>
> <idno>004</idno>
> <idno>005</idno>
> <idno>007</idno>
> <idno>009</idno>
> <idno>010</idno>
> <idno>011</idno>
> <idno>012</idno>
> <idno>020</idno>
> <idno>024</idno>
>
> Again, do you have any idea what went wrong?
>
> Thank you very much for your help!
>
> Best wishes,
> Peter


More information about the talk mailing list