MongoDB:geoNear没有返回距离

时间:2014-09-23 17:42:02

标签: javascript node.js mongodb mongoose geospatial

我需要修改现有的地理空间查询,使其包含搜索结果中的距离。 (文档和现有查询都使用遗留坐标对。)原始查询使用$ near。阅读MongoDB文档,看起来geoNear应该返回距离,如几个例子中所示。

虽然我能够修改查询以使用geoNear,但距离不包含在搜索结果中。以下是新查询的示例:

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

我不清楚的一件事是Mongo如何将查询中指定的位置与文档的位置联系起来。在我的例子中,用户文档有一个名为lastKnownPosition的字段。 Mongo甚至知道如何查询该字段?

以下是搜索结果的示例:

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

2 个答案:

答案 0 :(得分:0)

我想不出一个不会返回距离的案例。因此,您必须采取与此示例中的表示方式不同的内容:

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();
    }
  );

});

产生如下输出:

[ { 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 } ]

所有人都有#34;距离"字段,默认为" dis"并通过调用中的"geoNear"命令与文档分开,或者从聚合$geoNear运算符中指定并包含在文档中。

按照这些模式中的任何一种,您将获得所需的结果。

答案 1 :(得分:0)

每个集合只能创建一个2d索引,因此mongo直接知道要查询的字段。

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