【问题标题】:Mongoose calls to geoNear with GeoJSON points as query parameters not working使用 GeoJSON 点作为查询参数的 Mongoose 调用 geoNear 不起作用
【发布时间】:2014-05-02 16:06:38
【问题描述】:

给定一个为包含 GeoJSON 位置的文档定义的架构;


var BranchSchema = new Schema({
  location: {
    'type': {
      type: String,
      required: true,
      enum: ['Point', 'LineString', 'Polygon'],
      default: 'Point'
    },
    coordinates: [Number]
  },
  name: String
});
BranchSchema.index({location: '2dsphere'});

还有一些示例数据:


[
  {
    "name": "A",
    "location": {
      "type": "Point",
      "coordinates": [153.027117, -27.468515 ] //Brisbane, Australia
    }
  },
  {
    "name": "B",
    "location": {
      "type": "Point",
      "coordinates": [153.029884, -27.45643] //Also Brisbane, Australia
    }
  }
]

以下 geoNear 查询未按预期运行。我将此查询读为 “给定一个位于南美洲海岸的位置,在这些位置中进行拖网搜索,找到距离所提供位置 1 米范围内的任何位置。”


// Somewhere off the east coast of South America.
var point = {type: 'Point', coordinates: [0.0776590, -33.7797590]};

Branch.geoNear(point, {maxDistance:1, spherical: true}, function (err, data) {
  ...
  // at this point I expected data.length === 0.
  // Instead it is returning both documents.
  ...
});

我做错了什么?

  • 根据 WGS84 标准定义位置时,我使用 [long,lat]。
  • 运行 MongooseJS V3.8.8

【问题讨论】:

  • "此时我期望 data.length === 0" ?您为什么要在这里提供一份文件?您不会在任何地方限制结果。
  • Jayram 我不希望有任何结果,因为集合中的两个文档都应该在 [0.0776590, -33.7797590] 的 maxDistance 1 之外。我认为我的查询表达式有问题,但我不知道是什么:-)
  • 我在 mongoose 的 geonear 上遇到了同样的问题,因为它不起作用。我建议你手动或使用 $near。

标签: node.js mongodb mongoose geocoding


【解决方案1】:

问题是错误地使用了 maxDistance。以下表达式有效。


Branch.geoNear({type: "Point", coordinates: [0.0776590, -33.7797590]}, {
  spherical: true, 
  maxDistance: 1 / 6378137, 
  distanceMultiplier: 6378137
})
  .then(function (doc) {
    console.log(doc);
    process.exit();
  });


Mongoose: branches.ensureIndex({ location: '2dsphere' }) { safe: undefined, background: true }  
Mongoose: branches.geoNear(0.077659) -33.779759 { distanceMultiplier: 6378137, lean: true, maxDistance: 1.567855942887398e-7, spherical: true } 
[]

现在查询正确地发现集合中的两个文档不在查询位置的 1 米范围内。查询离家较近的位置也可以得到预期的结果。


Branch.geoNear({type: "Point", coordinates: [153.027117, -27.468515]}, {
  spherical: true, 
  maxDistance: 1 / 6378137, 
  distanceMultiplier: 6378137
})
  .then(function (doc) {
    console.log(doc);
    process.exit();
  });

Mongoose: branches.ensureIndex({ location: '2dsphere' }) { safe: undefined, background: true }  
Mongoose: branches.geoNear(153.027117) -27.468515 { distanceMultiplier: 6378137, lean: true, maxDistance: 1.567855942887398e-7, spherical: true } 
[ { dis: 0.0026823704060803567,
    obj: 
     { name: 'A',
       _id: 533200e49ba06bec37c0cc22,
       location: [Object],
       __v: 0 } } ]

解决方案?

geoNear 的 MongoDb 文档指出,如果使用 geoJSON 对象,maxDistance 应该以米为单位,如果使用坐标对,则以弧度为单位。

可选。距中心点的距离。为 GeoJSON 数据指定距离(以米为单位),为旧坐标对指定以弧度为单位的距离。 MongoDB 将结果限制在距中心点指定距离内的那些文档。 http://docs.mongodb.org/manual/reference/command/geoNear/#dbcmd.geoNear

这要么是错误的,要么是我对它的理解是错误的。

正如您在上面看到的,maxDistance 不是指定 1 米,而是以弧度提供。

截至本文发布之日,geoNear 要求 maxDistance 在 无论您使用的是 geoJSON 对象还是 旧坐标对。

【讨论】:

  • Github 上有一个未解决的问题:github.com/LearnBoost/mongoose/issues/1987
  • 我得到了错误的距离结果,直到我完全删除了 distanceMultiplier 选项,然后你意识到它不再是弧度而是 mts,MongoDB 版本 2.6.0,猫鼬 3.8.8:distanceMultiplier: 1
  • 你好,你介意看看我的+50赏金问题吗? stackoverflow.com/questions/37733030/… 和你遇到的这个问题有关。我非常感谢任何帮助。
【解决方案2】:

由于本地驱动程序的限制,Mongoose 正在将 geoJSON 点转换为旧坐标对; support has been added 到本机驱动程序,还有 an open PR 将此支持添加到 Mongoose。我已经更新了@NickB 提供的问题。

【讨论】:

    猜你喜欢
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 2021-04-26
    • 2011-08-03
    • 1970-01-01
    相关资源
    最近更新 更多