node.js - Mongoose $maxDistance 不精确

标签 node.js mongodb mongoose geolocation

我将位置存储在 Mongoose 模型中(名称 + 坐标为 [lng, lat])并在其上有一个 2d 索引。

我想获得距离以公里为单位的半径内的一个点(经度、纬度)最近的位置。

为此,我使用了 mongoose 的 $near 和 $maxDistance 参数。 我面临的问题是半径似乎不精确,因此我得到了错误的结果。

这是我的地理搜索代码:

LocationModel.find({
        loc: {
            $near: coords,
            $maxDistance: max_distance
        }
    }).exec(function(err, locations)
    {
        if(err)
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });

        res.json(locations);
    });

我有两个测试位置:

Place 1 : 6.614090000000033, 45.4203

Place 2 : 6.905578500000047, 45.4683226

Total distance : 23.36km

$maxDistance 的 max_distance 是这样计算的:

var max_distance = req.params.max_distance / 111.12;

当我提供引用点作为地点 A 时,我只会在将 max_distance 设置为 33 公里及以上时获得结果,而不是应有的 24 公里。

有人可以解释一下这里有什么问题吗?可能是 111.12(我在 Internet 上找到的),还是别的什么?

谢谢

最佳答案

既然你在谈论地理位置,我建议这些改变:

  1. 使用 2dsphere 索引代替 2d。这将确保搜索考虑到地球不是二维平面。
  2. 更改您的模型以表示 GeoJSON 格式的坐标。

所以你的模式应该是这样的:

    var LocationSchema = new mongoose.Schema({
      name: String,
      location: {
        type: {
           type: String,
           default: "Point"
        },
        coordinates: {
            type: [Number]
        }
      }
    });
    LocationSchema.index({ location: '2dsphere' });

现在您可以使用 Model.geoNear执行您的查询。要以公里为单位获取距离,您需要使用 distanceMultiplier 选项,并将地球半径(以公里为单位)作为值。不要忘记 { spherical: true } 标志。

注意:我将它用作聚合的一部分,它非常准确。在上述情况下它也应该工作相同。 Mongoose 文档没有谈论它。使用 this from MongoDB docs

关于node.js - Mongoose $maxDistance 不精确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30235602/

相关文章:

angularjs - 如何使用 Passport Js 将 mongodb 用户迁移到 Couchdb?

javascript - Meteor Select Box - 根据数据上下文将选项标记为选中

javascript - 在多个路由之间共享数据库连接?

node.js - 有条件需要 express 吗?

node.js - 如何使用 import 这个 npm 包?

java - 如何在Spring data mongodb中根据条件投影字段?

node.js - 当我在线部署应用程序时,Heroku 会崩溃,但在我的本地计算机上它可以正常工作,没有错误

javascript - 仅当 mongoDB Node JS 上存在集合时才显示给客户端

javascript - 限制半径内的对象数组并按距离排序

javascript - Sequelize 为 LIKE 添加额外的引号