[xquery-talk] paging mechanism

Philippe Michiels philippe.michiels at gmail.com
Fri Feb 3 12:49:41 PST 2006


That's a typo, the order by should order over $x. I tested it in Galax on a 
limited document (I do not know your schema) and it seems to work.

Try this one
let $sorted :=
  for $x in doc("test_data.xml")//text/body
  order by xs:decimal($x/idno) 
  return $x
return
  let $res := 
    for $x at $pos in $sorted
    where ($pos mod 50) < 2
    return $x/idno
  return
    for $y at $pos2 in $res
    where ($pos2 mod 2) > 0
    return
      <seq start="{$y}" end="{$res[$pos2+1]}">{
      fn:subsequence($sorted , $y, 50)
      }</seq>

Does this do what you expect?

-Ph

On Friday 03 February 2006 12:25, Peter Mueller wrote:
> Hi Philippe,
>
> > 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
>
> I tried your query, but it didn't work for me.
>
> It seems that you didn't replace the $doc by $x (?) and didn't put in a
> place to to bind to in the first line (?).
>
> [ I am quite new to XQuery - so please excuse that I might not understand
> your query and am not very familiar with the general syntax! ]
>
> I tried this query:
>
> for $x at $pos in //text/body/idno
> for $y in $x/body/idno
> order by xs:decimal($x) ascending
> return $y
> where ($pos mod 50) < 2
> return $x
>
> but still I got an error message telling me that (on line 5) there was an
> 'unexpected token "null" beyond end of query'
>
> Do you have any ideas what I did wrong?
>
> Thanks in advance,
> Peter
>
> P.S. I attached the test file so that you know the structure of the
> collection.
>
> > 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
> >
> > _______________________________________________
> > talk at xquery.com
> > http://xquery.com/mailman/listinfo/talk


More information about the talk mailing list