Query Service in WebSphere Portal WCM API

QueryService is a good addition to WCM API. It helps to keep the API neat and provides a way for developers to do “OR” condition (Disjunction class).

Below is a simple example on how to do a “Like” search on content’s title
(Do take note that Selectors.titleLike method is case-sensitive (as of 8.5) <- hope they will add in extra argument in future to allow us to decide if the title search should be case-sensitive)


Repository repository = WCM_API.getRepository();
Workspace ws = repository.getWorkspace();
ws.login();

QueryService queryService = ws.getQueryService();
Query query = queryService.createQuery(Content.class);
query.addSelector(Selectors.titleLike("%a%")); //searching for contents' title containing "a"

query.addSort(Sorts.byPublishDate(SortDirection.DESCENDING)); // sort by publish date
ResultIterator resultIter = queryService.execute(query);
while (resultIter.hasNext()) {
 Content content = (Content) resultIter.next();
 // process...
}

 

But we noticed that there are performance deficits when we try to traverse > 400 contents (~11 sec to complete). The deficit occurs when we tried to cast the object into its respective object types (for example (Content) resultIter.next()). We believe that the API is trying to clone the content’s internal document (including its respective elements).

Hence if you just need to reference the contents, perhaps you can try to retrieve content using the traditional Workspace.getById(DocumentId<T> id, boolean asReference, boolean loadElements) method (as this effectively reduce our time from 11 sec to just 1 sec on our side). Do let us know if it works for you, cheers!


Repository repository = WCM_API.getRepository();
Workspace ws = repository.getWorkspace();
ws.login();

QueryService queryService = ws.getQueryService();
Query query = queryService.createQuery(Content.class);
query.returnIds(); // get the query services to return DocumentId instead of Document objects
query.addSelector(Selectors.titleLike("%a%")); //searching for contents' title containing "a"

query.addSort(Sorts.byPublishDate(SortDirection.DESCENDING)); // sort by publish date
ResultIterator resultIter = queryService.execute(query);
while (resultIter.hasNext()) {
 Content content = (Content) ws.getById(((DocumentId) resultIter.next()),true,false); // only retrieve a reference Content without loading its elements
 // process...
}

 

Disjunction (Our favourite “OR” condition)

Below is a code snippet on how to retrieve contents based on “OR” categories condition (Disjunction).


Disjunction orCondForCats = new Disjunction();
// tranverse contents if they contains one of the selected categories
for (int i = 0, len = selectedList.size(); i &lt; len; i++) {
 orCondForCats.add(ProfileSelectors.categoriesContains(selectedList.get(i)));
}
query.addSelector(orCondForCats);

 

Conclusion:
We certainly will be using Query Service more often for our future projects. We also felt that the method has room  for improvements:

  • Provide a new execute method (similar to Workspace.getById(DocumentId<T> id, boolean asReference, boolean loadElements)) which allow developers to decide if the documents retrieve should be editable and loaded with elements. This should effectively improve the Query Service performance.
  • Provide an option to allow developers to perform case-insensitive search for content’s title.

Leave a Reply

Your email address will not be published. Required fields are marked *