user1094000
user1094000

Reputation: 207

Spring mongoTemplate. Sort is not working in geo query (NearQuery)

I have a problem with mongoTemplate in Spring when I am trying to query using NearQuery with a Sort. The Sort does not work:

Query query = new Query();
query.with(new Sort(Direction.DESC, "timeStamp"));
Criteria criteria = new Criteria();
criteria.and("type").is("MeasurementPoint");
query.addCriteria(criteria);

NearQuery queryN = NearQuery.near(p).maxDistance(new Distance(distance, Metrics.KILOMETERS)).num(range).query(query);
GeoResults<MeasurementPoint> geoPoints = mongoTemplate.geoNear(queryN, MeasurementPoint.class);

I do not know what I am doing wrong but the geoResult returns me the first match, not the last one (Sorted DESC). So, I assume that the Sort is not working properly.

Any idea? Is it a bug?

Thanks!

Upvotes: 1

Views: 3964

Answers (1)

Miguel Cartagena
Miguel Cartagena

Reputation: 2606

Unfortunately, isn't possible sort geoNear results since it doesn't returns a cursor and the default sort is the distance with point. What you could do is sort the results manually in Java code. Note that the code bellow ignores the distance and sorts only by "timeStamp".

List<GeoResult<Person>> results = geoPoints.getContent();
Collections.sort(results, new Comparator<GeoResult<Person>>() {
    @Override
    public int compare(GeoResult<Person> o1, GeoResult<Person> o2) {
        return o1.getContent().getTimeStamp() == 2.getContent().getTimeStamp() ? 0 : 
                (o1.getContent().getTimeStamp() > o2.getContent().getTimeStamp() ? 1 : -1) ;
        }
    });

An alternative approach is use $geoWithin and $centerSphere. Since you're limiting results with some distance (distance variable), that could work.

    Query query = Query.query(Criteria.where("coords").withinSphere(new Circle(p, new Distance(distance, Metrics.KILOMETERS).getNormalizedValue())));
    query.with(new Sort(Direction.DESC, "timeStamp"));
    Criteria criteria = new Criteria();
    criteria.and("type").is("MeasurementPoint");
    query.addCriteria(criteria);

    List<Person> geoPoints = mongoTemplate.find(query, MeasurementPoint.class);

You could find more information about $geoWithin and $centerSphere here:

http://docs.mongodb.org/manual/reference/operator/geoWithin/

http://docs.mongodb.org/manual/reference/operator/centerSphere/

Upvotes: 2

Related Questions