Apache CMIS: Paging query result

5.8k views Asked by At

Recently I've started using Apache CMIS and read the official documentation and examples. I haven't noticed anything about paging query results.

There is an example showing how to list folder items, setting maxItemsPerPage using operationContext, but it seems that operationContext can be used inside getChilder method:

int maxItemsPerPage = 5;
int skipCount = 10;
CmisObject object = session.getObject(session.createObjectId(folderId));
Folder folder = (Folder) object;
OperationContext operationContext = session.createOperationContext();
operationContext.setMaxItemsPerPage(maxItemsPerPage);
ItemIterable<CmisObject> children = folder.getChildren(operationContext);
ItemIterable<CmisObject> page = children.skipTo(skipCount).getPage();

This is ok when it comes to listing u folder. But my case is about getting results from custom search query. The basic approach is:

String myType = "my:documentType";
ObjectType type = session.getTypeDefinition(myType);
PropertyDefinition<?> objectIdPropDef = type.getPropertyDefinitions().get(PropertyIds.OBJECT_ID);
String objectIdQueryName = objectIdPropDef.getQueryName();
String queryString = "SELECT " + objectIdQueryName + " FROM " + type.getQueryName();
ItemIterable<QueryResult> results = session.query(queryString, false);
for (QueryResult qResult : results) {
    String objectId = qResult.getPropertyValueByQueryName(objectIdQueryName);
    Document doc = (Document) session.getObject(session.createObjectId(objectId));
}

This approach will retrieve all documents in a queryResult, but I would like to include startIndex and limit. The idea would be to type something like this:

ItemIterable<QueryResult> results = session.query(queryString, false).skipTo(startIndex).getPage(limit);

I'm not sure about this part: getPage(limit). Is this right approach for paging? Also I would like to retrieve Total Number of Items, so I could know how to set up the max items in grid where my items will be shown. There is a method, but something strange is written in docs, like sometimes the repository can't be aware of max items. This is that method:

results.getTotalNumItems();

I have tried something like:

SELECT COUNT(*)...

but that didn't do the trick :)

Please, could you give me some advice how to do a proper paging from a query result?

Thanks in advance.

1

There are 1 answers

0
Jeff Potts On BEST ANSWER

Query returns the same ItemIterable that getChildren returns, so you can page a result set returned by a query just like you can page a result set returned by getChildren.

Suppose you have a result page that shows 20 items on the page. Consider this snippet which I am running in the Groovy Console in the OpenCMIS Workbench against a folder with 149 files named testN.txt:

int PAGE_NUM = 1
int PAGE_SIZE = 20
String queryString = "SELECT cmis:name FROM cmis:document where cmis:name like 'test%.txt'"

ItemIterable<QueryResult> results = session.query(queryString, false, operationContext).skipTo(PAGE_NUM * PAGE_SIZE).getPage(PAGE_SIZE)

println "Total items:" + results.getTotalNumItems()

for (QueryResult result : results) {
   println result.getPropertyValueByQueryName("cmis:name")
}

println results.getHasMoreItems()

When you run it with PAGE_NUM = 1, you'll get 20 results and the last println statement will return true. Also note that the first println will print 149, the total number of documents that match the search query, but as you point out, not all servers know how to return that.

If you re-run this with PAGE_NUM = 7, you'll get 9 results and the last println returns false because you are at the end of the list.

If you want to see a working search page that leverages OpenCMIS and plain servlets and JSP pages, take a look at the SearchServlet class in The Blend, a sample web app that comes with the book CMIS & Apache Chemistry in Action.