title: Finding Closest Points to a certain Point Given its Coordinates and Maximum Distance - Query Result Undefined using Mongoose with MEAN Stack
body: <p>I've an issue that I wasn't able to solve in some days, even looking at related Stack Overflow Q/A.</p>
  
  <p>I'm developing an application reusing <a href="https://scotch.io/tutorials/making-mean-apps-with-google-maps-part-i" rel="noreferrer">Scotch's Create a MEAN Stack Google Map App Tutorial by Ahmed Haque</a> approach.</p>
  
  <p>I'm trying to implement an application that uses <strong>Google Maps API</strong> to draw <code>Points</code>, <code>LineStrings</code> and <code>Polygons</code> which coordinates are contained in <strong>GeoJson</strong> files that are stored in a <strong>MongoDB</strong> instance.</p>
  
  <p>I'm using <code>Mongoose</code> to build the Schema for my data and query my <code>MongoDB</code> database. </p>
  
  <blockquote>
    <p>I would like to find the closest Points <code>CP</code> to a certain Points <code>P0</code>
    given <code>P0's latitude and longitude</code> and given a maximum radius
    <code>distance</code> used to find the interested points.</p>
  </blockquote>
  
  <p><a href="https://i.stack.imgur.com/2Z8fF.png" rel="noreferrer"><img src="https://i.stack.imgur.com/2Z8fF.png" alt="enter image description here"></a></p>
  
  <p>Given the image over, I would like that, for example, if I insert 2000 (kilometers), my query will find all the points maximum 2000 kilometers away from P0. In this example, it should probably give me P1 and P2.</p>
  
  <p>I was able to do it when I only had Points in my <code>Mongoose Schema</code>.</p>
  
  <p><strong>I had this <code>Schema</code> with only markers (Points)</strong>:</p>
  
  <pre><code>// Pulls Mongoose dependency for creating schemas
  var mongoose    = require('mongoose');
  var Schema      = mongoose.Schema;
  
  // Creates a User Schema. 
  var MarkerSchema = new Schema({
      username: {type: String, required: true},
      location: {type: [Number], required: true}, // [Long, Lat]
      created_at: {type: Date, default: Date.now},
      updated_at: {type: Date, default: Date.now}
  });
  
  // Indexes this schema in 2dsphere format
  MarkerSchema.index({location: '2dsphere'});
  
  module.exports = mongoose.model('mean-markers', MarkerSchema);
  </code></pre>
  
  <p><strong>And this was my <code>Old Query for only Markers</code>:</strong></p>
  
  <pre><code>var User = require('./model.js');
  
  app.post('/query/', function(req, res) {
  
          // Grab all of the query parameters from the body.
          var lat = req.body.latitude;
          var long = req.body.longitude;
          var distance = req.body.distance;
          var reqVerified = req.body.reqVerified;
  
          // Opens a generic Mongoose Query
          var query = User.find({});
  
          // ...include filter by Max Distance (converting miles to meters)
          if (distance) {
  
              // Using MongoDB's geospatial querying features
              query = query.where('location').near({
                  center: {
                      type: 'Point',
                      coordinates: [long, lat]
                  },
  
                  // Converting meters to miles
                  maxDistance: distance * 1609.34,
                  spherical: true
              });
          }
  });
  </code></pre>
  
  <p>It worked really well, and I was able to get close points.</p>
  
  <p>Then, I changed my <code>Schema</code> to be more dynamic and also support <code>Polylines and Polygons</code>. </p>
  
  <p><strong>I'm able to insert and draw new Points, Polylines and Polygons with the following <code>Schema</code>:</strong> </p>
  
  <pre><code>var mongoose = require('mongoose');
  var GeoJSON  = require('geojson');
  var Schema   = mongoose.Schema;
  
  // Creates a Location Schema.
  var LocationSchema = new Schema({
                                      name: {type: String, required: true},
                                      location: {
                                        type: {type : String, required: true},
                                        coordinates : [Schema.Types.Mixed]
                                      },
                                      created_at: {type: Date, default: Date.now},
                                      updated_at: {type: Date, default: Date.now}
  });
  
  LocationSchema.index({location: '2dsphere'});
  module.exports = mongoose.model('mean-locations', LocationSchema);
  </code></pre>
  
  <p><strong>And this is my <code>Mongoose Query</code>:</strong></p>
  
  <pre><code>var GeoObjects = require('./model.js');
  
  app.post('/query/', function(req, res) {
  
      // Grab all of the query parameters from the body.
      var lat = req.body.latitude;
      var long = req.body.longitude;
      var distance = req.body.distance;
  
      var query;
  
      if (distance) {
          query = GeoObjects.find({'location.type':'Point'})
                      .where('location.coordinates').near({
                        center: {
                          type: 'Point',
                          coordinates: [lat, long]
                        },
                        // Converting meters to miles
                        maxDistance: distance * 1609.34,
                        spherical: true
          });
      }
  
      // Execute Query and Return the Query Results
      query.exec(function(err, users) {
          if (err)
              res.send(err);
          console.log(users);
          // If no errors, respond with a JSON of all users that meet the criteria
          res.json(users);
      });
  });
  </code></pre>
  
  <p><code>console.log(users);</code> gives me <code>undefined.</code></p>
  
  <p>Logging query results in my <strong>queryCtrl.js</strong> gives me the following error message:</p>
  
  <p><code>name: "MongoError", message: "error processing query: ns=MeanMapApp.mean-locatio…ed error: unable to find index for $geoNear query", waitedMS: 0, ok: 0, errmsg: "error processing query: ns=MeanMapApp.mean-locatio…ed error: unable to find index for $geoNear query"</code></p>
  
  <p><strong>Same with a little variation:</strong></p>
  
  <pre><code>app.post('/query/', function(req, res) {
  
      // Grab all of the query parameters from the body.
      var lat = req.body.latitude;
      var long = req.body.longitude;
      var distance = req.body.distance;
  
      console.log(lat,long,distance);
  
      var points = GeoObjects.find({'location.type':'Point'});
  
      var loc = parseFloat(points.location.coordinates);
      console.log(JSON.stringify(loc));
  
      if (distance) {
          var query = points.near(loc, {
                        center: {
                          type: 'Point',
                          coordinates: [parseFloat(lat), parseFloat(long)]
                        },
                        // Converting meters to miles
                        maxDistance: distance * 1609.34,
                        spherical: true
          });
      }
  });
  </code></pre>
  
  <p><strong>This is an example of a marker:</strong></p>
  
  <pre><code>{
    "name": "user01",
    "location": {
                  "type":"Point",
                  "coordinates": [102.0, 0.0]
  
    }
  }
  </code></pre>
  
  <p><strong>How $near operator works with distance and maxDistance:</strong></p>
  
  <p>From <a href="https://scotch.io/tutorials/making-mean-apps-with-google-maps-part-ii" rel="noreferrer">Scotch's Making MEAN Apps with Google Maps (Part II) by Ahmed Haque</a></p>
  
  <blockquote>
    <p>MongoDB search parameter $near and its associated properties
    maxDistance and spherical to specify the range we’re looking to cover.
    We’re multiplying the distance of our query body by 1609.34, because
    we want to take our users’ input (in miles) and convert it into the
    units MongoDB expects (in meters).</p>
  </blockquote>
  
  <ol>
  <li><strong>Why Am I getting <code>undefined</code>?</strong></li>
  <li><strong>Is it possible that this problem is caused by my Schema?</strong></li>
  <li><strong>How can I fix this?</strong></li>
  </ol>
  
  <p>If you would like to receive some clarifications just post a comment below.</p>
  
  <p>Thanks in Advance.</p>