Hail fellow, well met.
I've been playing around with MongoDB lately, specifically its map/reduce functionality, and I was hoping someone out there might be able to lend a hand.
I am trying to find a simple way to page through a results set from a Mongo data base. This page will be displayed on a jsp page using Spring MVC.
From my previous tests, querying the database and forming a page are pretty straight forward:
This works without an issue: the results list is sorted in descending order according to each element's timeStamp field, each page has the correct number of elements, I can enter new values for currentPage and I get the expected result, etc, etc.Code://Create page request and form a query PageRequest pageRequest = new PageRequest(currentPage, totalOnPage, Sort.Direction.DESC, "timeStamp"); Query query = queryConstructor.formQuery(formData); query.with(pageRequest); //use above query to get results, stick those results in a page, add page to the model List<LogRecord> results= mongoTemplate.find(query, LogRecord.class) PageImpl<LogRecord> page = new PageImpl<LogRecord>(results, pageRequest, COLLECTION_NAME.count()); model.add("logRedcords", page);
The issue comes when I try to repeat this same approach using the mongoTemplate.mapReduce(..) function, as follows:
This works (kind of). The page I add to the model has the ENTIRE results set, not just the first numberOnPage. The elements are not even in decending order according to their timeStamp field, or any field for that matter.Code:PageRequest pageRequest = new PageRequest(currentPage, totalOnPage, Sort.Direction.DESC, "timeStamp"); Query query = queryConstructor.formQuery(formData); //query.with(pageRequest); <- This breaks everything mayan 2012 style, so I'll skip over it for now. MapReduceResults<ThreadReport> results = mongoTemplate.mapReduce(query, COLLECTION_NAME, MAP_FUNCTION, REDUCE_FUNCTION, ThreadReport.class); List<ThreadReport> listResults= turnIntoList(results); PageImpl<ThreadReport> page = new PageImpl<ThreadReports>(listResults, pageRequest, COLLECTION_NAME.count()); model.add("threadReports", page);
The map and reduce functions work fine, they do everything I'm asking. The results set also is totally correct and everything I expect to be in there is.
The problem is just splitting up the results via PageRequest and PageImpl (using the same approach as I did in the first example).
The problem *could* be that I am unable to perform the query.with(pageRequest) call. I skipped over it because it crashes the whole program. I read in the documentation that you cannot perform Mongo's mapReduce(..) call and Mongo's skip() call in the same operation, which I only guess query.with(Pageable) uses behind the curtains.
So, I came up with the following work around:
Maintain the huge results list in some wrapper class.
Sort that list based on my needs.
When the user requests a new page, iterate from the bottomIndex = n*totalOnPage element to the topIndex = bottomIndex + (totalOnPage-1) element.
Stick those elements in a new list
Stick that new list in a PageImpl and stick the page in the model.
What do you guys think? Am I working to hard? Does the framework have this functionality already built into it and I just haven't discovered it yet?
Thanks a million. Hope to hear back before the end of the world, don't want to go out not knowing.
P.S. I may/may not be a newb.


Reply With Quote
