Hippo Site Toolkit Query interface and pagination
Today an interesting question came from a developer of one of our implementation partners. He wanted to list items from our JCR repository and use pagination. In this post I tried to make a summary out of the conversation.
The query was:
HstQuery query =
getQueryManager().createQuery(requestContext, scope, filterBean);
Filter filter = query.createFilter();
filter.addContains(".", "my keywords");
HstQuery queryResult = query.execute();
The developer tried to get a paged result and the total number of items with:
HippoBeanIterator hits = queryResult.getHippoBeans();
The result contained indeed 10 items but
hits.getSize(); also returned 10. What’s going wrong? Ard Schrijvers explained:
If you use
setLimit(3), you will get at most 3 hits, but never more.
queryResultreturns at most 3. Even if the search criteria matched hundreds of documents. If you use
offset(10)and no limit,
getSize()returns just 10 hits less then without the offset.
This limit is there to be used for performance, and suits for example very well "show last 3 agenda items on homepage".
If you need paging and only want 10 results, do not use
What you do use, is just the query without
setLimit(). Then you’ll get back a
queryResult, from which you get a
HippoBeanIterator. This is a normal
Iterator, with some extensions. A very important one is the method
HippoBeanIterator, you can simply iterate the beans you need. Make sure you use
skip(int skipNum)to jump to the correct place. If the current page is 11 and pagesize is 20, set
Then fill your
Listin a for loop from
skipNum — skipNum + pageSize.
What about performance?
The skip is propagated to the JCR
NodeIterator. If you want to display item 100-110, and you use
skip(100), still only 10 Beans will be created. JCR nodes for Beans 0-99 are not fetched.
What if you need the total number of hits?
getSize()on the the
HstQueryResultImplor on the
HippoBeanIteratorImpldoes not actually populate the entire iterator with
HippoBeans. It is a call through the JCR
NodeIterator, which in JackRabbit is some lazy loading iterator, and, where the
getSize()is propagated to the executed query, without fetching actual nodes.