Question

I'm using spring-data-mongodb to do the pagination on MongoDB geo results.

Here's the relevant code (with MongoTemplate):

Query query = new Query();
query.addCriteria(where("location").nearSphere(new Point(longitude, latitude)).maxDistance(0.012));
query.with(pageable);

//On any page other than the first page
//the following list is always empty (although the total number of records is much bigger than the page size)
List<MyObject> myObjects = mongoTemplate.find(query, MyObject.class);

The the first page (i.e., page:0, size:5) always shows up correctly, all other pages (i.e., page:1, size:5) contain no results, since the above List would be empty.

If I comment out the line 2 //query.addCriteria(where("location").nearSphere(...), the pagination works properly.

By the way, I can't use mongoTemplate.geoNear() since it doesn't support include/exclude according to this

I'm using spring-data-mongodb-1.5.0.RELEASE and mongodb 2.6.1

Any idea how to solve this problem? Thanks.

Was it helpful?

Solution

I found a workaround myself. It seems MongoDB has inconsistent behaviour on 'skip + limit' between $nearSphere (may be also $near) and other queries.

While you can do

db.doc.find().skip(10).limit(5)

with 'regular' queries, you have to use

db.doc.find({
   'location': {
       $nearSphere: ...,
       $maxDistance: ...
   }
}).skip(10).limit(15) //note the number for limit has to be 15, which
                      //is 'offset + pageSize' <==> '10 + 5'

for $nearSphere queries.

So in spring-data-mongodb, with mongoTemplate, you can do this

int offset = pageable.getOffset();
query.skip(offset);
query.limit(offset + pageable.getPageSize());
...
mongoTemplate.find(query, ...);

instead of

query.with(pageable);
...
mongoTemplate.find(query, ...);

That gave me the expected results (with MongoDB 2.6.1 + Spring Data MongoDB 1.5.1).

I can't say if this is a bug of MongoDB, but at least it looks confusing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top