MongoDB: geoNear not returning distance

I need to modify an existing geospatial query so that it includes the distance in the search results. (Both the document and the existing query are using legacy coordinate pairs.) The original query uses $near. Reading the MongoDB documentation it looks like geoNear should return distance, as is shown in several examples.

While I have been able to modify the query to use geoNear, the distances are not included in the search results. Here is an example of the new query:

{ 
  geoNear: 'users',
  near: [ '0', '0' ],
  maxDistance: '90',
  query: { userName: { '$regex': '^test' } }
}

One thing that's not clear to me is how Mongo ties the location to the specified in the query to the location of the document. In my case the users document has a field named lastKnownPosition. How does Mongo even know to query against that field?

Here's an example of the search results:

{ 
    "__v" : 0 , 
    "_id" : { "$oid" : "5413824f8b4d6f7505120a53"} , 
    "lastKnownPosition" : { "lon" : 0 , "lat" : 0} ", 
    "userName" : "test123"
}

I cannot think of a single case where a distance would not be returned. So you must be doing something different to how this is represented in this sample:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');

var geoSchema = new Schema({
  "lastKnownPosition": {
    "lon": Number,
    "lat": Number
  },
  "userName": String
});

geoSchema.index({ "lastKnownPosition": "2d" });

var Geo = mongoose.model( "Geo", geoSchema, "testgeo" );

mongoose.connection.on("open", function(err,conn) {

  async.series(
    [

      function(callback) {
        Geo.remove({},function(err) {
          callback();
        });
      },

      function(callback) {
        Geo.create(
          {
            "lastKnownPosition": { "lon": 0, "lat": 0 },
            "userName": "test123"
          },
          function(err,doc) {
            if (err) throw err;
            callback();
          }
        );
      },

      // Mongoose method
      function(callback) {
        Geo.geoNear(
          [0,0],
          {
            maxDistance: 90,
            query: { 'userName': { '$regex': '^test' } }
          },
          function(err,docs) {
            if (err) throw err;
            console.log( docs );
            callback();
        });
      },

      // Native method
      function(callback) {
        Geo.db.db.executeDbCommand(
          {
            "geoNear": "testgeo",
            "near": [ 0, 0 ],
            "maxDistance": 90,
            "query": { 'userName': /^test/ },
          },function(err,result) {
            if ( err ) throw err;
            console.log( result.documents[0].results[0] );
            callback();
          }
        );
      },

      // aggregate method
      function(callback) {
        Geo.aggregate(
          [
            { "$geoNear": {
              "near": [0,0],
              "distanceField": "distance",
              "maxDistance": 90,
              "query": { "userName": { "$regex": "^test" } }
            }}
          ],
          function(err,result) {
            if (err) throw err;
            console.log( result );
            callback();
          }
        );
      }
    ],
    function(err) {
      mongoose.disconnect();
    }
  );

});

Which produces output like the following:

[ { dis: 0,
    obj:
     { userName: 'test123',
       __v: 0,
       _id: 54225696ce2837e4495cd188,
       lastKnownPosition: { lon: 0, lat: 0 } } } ]
{ dis: 0,
  obj:
   { _id: 54225696ce2837e4495cd188,
     userName: 'test123',
     lastKnownPosition: { lon: 0, lat: 0 },
     __v: 0 } }
[ { _id: 54225696ce2837e4495cd188,
    userName: 'test123',
    lastKnownPosition: { lon: 0, lat: 0 },
    __v: 0,
    distance: 0 } ]

All have a "distance" field, which is defaulted to "dis" and separate to the document by what is the "geoNear" command in either invocation or is specified and included within the document from the aggregate $geoNear operator.

Follow any of those patterns and you will get the results you want.

You can only create one 2d index per collection, so mongo directly knows which field to query against.

http://docs.mongodb.org/v2.2/core/geospatial-indexes/#create-a-geospatial-index