Question

I have some geospatial data in MongoDB and I want to find list of places which are near User's location and match certain criteria.

Here is my document structure:

{ "_id" : { "$oid" : "528af043d1a2760efcd2fd2f" }, "city" : "Miami", "name" : "Some Place", "tickets" : 61, "zipcode" : "33142", "type" : "amusement park", "state" : "FL", "location" : [ -80.24, 25.8092 ]}
{ "_id" : { "$oid" : "528af043d1a2760efcd2fd30" }, "city" : "Miami", "name" : "Other place", "tickets" : 15, "zipcode" : "33150", "type" : "theatre", "state" : "FL", "location" : [ -80.2094, 25.8587 ]}

Now I am trying to find places through latitude, longitude, which have tickets available and are of certain kind. When I just use NearQuery with coordinates (without adding query), I am getting results, but when I add query object I am getting empty list.

Here is my code:

public GeoResults<Place> find(double lat, double lon, int tickets, String type) {
    Point point = new Point(lon, lat);

    Query query = new Query(Criteria.where("tickets").gt(tickets).
            and("type").is(type));
    NearQuery nearQuery = NearQuery.near(point).maxDistance(new Distance(10, Metrics.KILOMETERS));
    nearQuery.query(query);
    GeoResults<Place> repoData = repo.findByLocationNear(point, new Distance(10, Metrics.KILOMETERS));

    GeoResults<Place> data = mongoTemplate.geoNear(nearQuery, Place.class);         
    List<Place> testData = mongoTemplate.find(query, Place.class);

    return data;
}

From above code, GeoResults data has no contents while List testData returns proper results(but does not uses spatial information). If I use repository, I can get list of places but that does not takes additional parameters into consideration.

Thanks in Advance

Was it helpful?

Solution

I found one way to do it myself. I debugged code all the way into Spring-mongodb library and saw that 'num' was set to 0 and 'fields' was set to null. So during debugging I added fields manually and provided a value to number of documents it should retrieve. My assumption was that it should return all fields and any number of documents matching the criteria.

Here is the updated code to create a query:

Query query = new Query(Criteria.where("tickets").gt(tickets).
            and("type").is(type));
query.fields().include("city").include("name").include("tickets").
include("type").include("state").include("address");

NearQuery nearQuery = NearQuery.near(point).maxDistance(new Distance(radius, Metrics.KILOMETERS));
nearQuery.query(query);
nearQuery.num(100);

GeoResults<Place> data = mongoTemplate.geoNear(nearQuery, Place.class); 

OTHER TIPS

I had the same problem and after a long struggle I finally found the root cause of my problem.

1. NearQuery.near(point).maxDistance(distance); //returns all possible results
2. NearQuery.near(point).maxDistance(distance).num(20); //returns 20 nearest results   
3. NearQuery.near(point).maxDistance(distance).num(20).query(new Query()); //returns 0!! results
4. NearQuery.near(point).maxDistance(distance).query(new Query()).num(20); //returns 20 nearest results
5. NearQuery.near(point).maxDistance(distance).query(new Query().limit(20)); //returns 20 nearest results
6. NearQuery.near(point).maxDistance(distance).query(new Query().limit(20)).num(5); //returns 5!! nearest results

The reason why the third NearQuery has 0 results is due to the fact that the .query(...) part of the NearQuery class does this:

public NearQuery query(Query query) {
    this.query = query;
    this.skip = query.getSkip();
    this.num = query.getLimit();
    return this;
}

The parameter num of NearQuery is overridden by the limit of the Query. The order of .num(...) and .query(...) is really important. You have to add .num(20) after .query(...) like (4) or use query.limit(20) like (5). If you combine both, the last value wins (6).

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