How to find nearby points using latitude and longitude in mongo db using mongoose

Viewed 966

Schema:

const locationSchema = new mongoose.Schema({
    id:String,
    name:{type: String , required:true},
    address:String,
    rating:{type:Number , "default":0, min:0 , max:5 },
    facilities:[String],
    // geoJSON schema 1
    coords: 
    {
        type: {type: String},
        coordinates:[]

    },

    openingTimes: [openingTimeSchema],
    reviews: [reviewSchema]
    });

    locationSchema.index({'coords':'2dsphere'})

endpoint : http://localhost:3000/api/locations?lng=-0.7992599&lat=51.378091

const theEarth = (function() {
    console.log('theEarth');
    const earthRadius = 6371; // km, miles is 3959

    const getDistanceFromRads = function(rads) {
      return parseFloat(rads * earthRadius);
    };

    const getRadsFromDistance = function(distance) {
      return parseFloat(distance / earthRadius);
    };

    return {
      getDistanceFromRads: getDistanceFromRads,
      getRadsFromDistance: getRadsFromDistance
    };
  })();

module.exports.locationsListByDistance = (req,res) => {

    const longitude = parseFloat(req.query.lng);
    const latitude = parseFloat(req.query.lat);
    //const maxDistance = parseFloat(req.query.maxDistance);
     Loc.aggregate(
        [{
            $geoNear: {
                near: { type: "Point", coordinates: [ longitude , latitude ] },
                distanceField: "coords.calculated", // required
                maxDistance: theEarth.getRadsFromDistance(20),
                includeLocs: "coords.location",
                spherical:true


              }

            }
        ],function(err,results){
            console.log(results);
        });




    sendJsonResponse(res,200,results);

};

Error:

UnhandledPromiseRejectionWarning: MongoError: There is more than one 2dsphere index on Loc8r.locations; unsure which to use for $geoNear
    at MessageStream.messageHandler (E:\Udemy\NodeTutorial\getting-mean\loc8r\node_modules\mongodb\lib\cmap\connection.js:261:20)      
    at MessageStream.emit (events.js:198:13)
    at processIncomingData (E:\Udemy\NodeTutorial\getting-mean\loc8r\node_modules\mongodb\lib\cmap\message_stream.js:144:12)
    at MessageStream._write (E:\Udemy\NodeTutorial\getting-mean\loc8r\node_modules\mongodb\lib\cmap\message_stream.js:42:5)
    at doWrite (_stream_writable.js:415:12)
    at writeOrBuffer (_stream_writable.js:399:5)
    at MessageStream.Writable.write (_stream_writable.js:299:11)
    at Socket.ondata (_stream_readable.js:709:20)
    at Socket.emit (events.js:198:13)
    at addChunk (_stream_readable.js:288:12)
    at readableAddChunk (_stream_readable.js:269:11)
    at Socket.Readable.push (_stream_readable.js:224:10)
    at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
(node:5040) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async 
function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
GET /bootstrap/bootstrap.min.css 304 0.954 ms - -
GET /stylesheets/style.css 304 5.782 ms - -
GET /api/bootstrap/jquery.min.js 404 65.965 ms - 3123
GET /api/bootstrap/bootstrap.min.js 404 116.055 ms - 3123

I am using the above approach in order to find the documents whose distance is nearby the longitude and latitude put in the query params in the endpoint but results is returning undefined, please tell how to correct this error.

2 Answers
module.exports.locationsListByDistance = (req,res) => {

        const longitude = parseFloat(req.query.lng);
        const latitude = parseFloat(req.query.lat);
        //const maxDistance = parseFloat(req.query.maxDistance);
       // const options = {near :[longitude,latitude],maxDistance:10000}
        Loc.find({

          coords: {
            $near : {


              $maxDistance: 10,
              $geometry : {
                type : 'Point',
                coordinates:[longitude,latitude]
              }
            }
          }
        }).find((error,results)=>{
          if (error) console.log(error);
        //console.log(JSON.stringify(results, 0, 2));
        sendJsonResponse(res,200,results);
        });

       };

This is working fine.

You basically have multiple 2dsphere indexes. You must specify the one to use for this query. Try modifying your geoNear query to include the correct index:

$geoNear: {
near: { type: "Point", coordinates: [longitude, latitude] },
distanceField: "coords.calculated", // required
maxDistance: theEarth.getRadsFromDistance(20),
includeLocs: "coords.location",
spherical: true,
key: 'indexName'}
Related