0

The following query should return cities within a distance of lng and lat. The city collection has an 2dsphere index on its gps field.

City.native(function(err, collection) {
    collection.aggregate([{
        $geoNear: {
            near: {
                type: 'Point',
                coordinates: [lng, lat]
            },
            distanceField: 'dist',
            limit: limit,
            maxDistance: distance,
            distanceMultiplier: 1,
            spherical: true
        }
    }], function(err, result) {
            return res.send(result);
        }
    });
});

My problem is that when I set distance to 0 the query still returns documents with e.g.

"dist": 27507.15237596358

But it shouldn't return anything because there is no city within a distance of 0. Any ideas what I am doing wrong?


Query:

lat=51.9637151&lng=8.5610982&distance=1

returns a document with following position:

"gps": {
  "type": "Point",
  "coordinates": [
    8.906756,
    52.030319
  ]
},
"dist": 24824.18378549408

But maxDistance is set to 1.


Before I used aggregation in the code above I used this code and it worked:

City.native(function(err, collection) {
    collection.geoNear(lng, lat, {
        limit: limit,
        maxDistance: maxDistance / 6371, // in km
        distanceMultiplier: 6371, // converts radians to miles (use 6371 for km)
        spherical: true
}, function(err, result) {});

However when I changed to aggregation it stopped working.

DarkLeafyGreen
  • 69,338
  • 131
  • 383
  • 601
  • *[para]"Setting to 0 should return no results..."* Why would you want to do that? Set it to anything but 0 and it will work as expected. – Neil Lunn Sep 16 '14 at 07:24
  • @NeilLunn even if I set it to 1 it returns all documents instead of zero documents – DarkLeafyGreen Sep 16 '14 at 07:28
  • Cannot reproduce. [ 151.00211262702942, -33.81696995135973 ] is 8753 meters from [ 150.92094898223877, -33.77654333272719 ]. Any number lower than that does not select the document. But `0` of course does because you **never** query for a deliberate no result. Perhaps you should show some data, which is likely your problem here. – Neil Lunn Sep 16 '14 at 07:32
  • @NeilLunn have a look at my updated question. – DarkLeafyGreen Sep 16 '14 at 07:56
  • Still cant replicate. You do actually have "maxDistance" and not "maxdistance" instead? And there is only one "2dsphere" index on this collection – Neil Lunn Sep 16 '14 at 08:06
  • @NeilLunn yes, only one 2dsphere index and maxDistance in camel case. I updated my question with more details. – DarkLeafyGreen Sep 16 '14 at 08:10
  • What is this `.native()` function you are using? This seems to come from some type of "document mapper" where it is a means for getting the underlying collection object. I'm not familiar with anything that has this method to do so though. Possibly a source of your problem as the native driver by itself works as expected. – Neil Lunn Sep 16 '14 at 08:47
  • @NeilLunn exactly! I am using the node MVC framework sails.js which uses mongo-node (if you set so, it supports a lot of databases). While sails.js has its own object db abstraction called waterline I can use the native() method to get access to the mongo-node layer. – DarkLeafyGreen Sep 16 '14 at 08:51
  • I would suggest here that `.native()` is not truly returning an actual collection object and is possibly doing some "filtering" of arguments on it's own. I know "waterline" is a bit funny like that as it tries to "abstract" and be all things to all databases. – Neil Lunn Sep 16 '14 at 08:53

1 Answers1

1

I solved it with following query:

$geoNear: {
   near: {
      type: 'Point',
      coordinates: [lng, lat]
   },
   distanceField: 'dist',
   limit: limit,
   maxDistance: distance * 1000,
   distanceMultiplier: 1 / 1000,
   spherical: true
}

It seems that maxDistance accepts values as meters. So if I want it to accept KM I need to multiply it by 1000. To output distance as KM the distanceMultiplier has to be 1/1000.

DarkLeafyGreen
  • 69,338
  • 131
  • 383
  • 601