资讯专栏INFORMATION COLUMN

关于Mongoose的geoNear方法的使用

Airy / 3160人阅读

摘要:背景最近在学习,看的是的这本书。其中中涉及到了的方法的使用。不过自己在按照作者的方法进行测试的时候,发现并不能输出想要的结果。通过相关研究找到了解决的方法,因此分享。

背景

最近在学习MEAN,看的是Simon HelmesGetting MEAN with Mongo, Express, ANgular, and Node这本书。其中Chapter 8 Adding Angular components to an Express application中涉及到了MongoosegeoNear方法的使用。不过自己在按照作者的方法进行测试的时候,发现并不能输出想要的结果。通过相关研究找到了解决的方法,因此分享。

问题

作者在书中演示了通过浏览器的navigator.geolocation发送经纬度坐标到API接口,接着后台使用MongoosegeoNear方法,从数据库中将离目标坐标较近的数据推送出来。后台从Mongo中取数的大致代码如下:

/* GET list of locations */
module.exports.locationsListByDistance = function(req, res) {
  var lng = parseFloat(req.query.lng);
  var lat = parseFloat(req.query.lat);
  var maxDistance = parseFloat(req.query.maxDistance);
  var point = {
    type: "Point",
    coordinates: [lng, lat]
  };
  var geoOptions = {
    spherical: true,
    maxDistance: theEarth.getRadsFromDistance(maxDistance),
    num: 10
  };
  if ((!lng && lng!==0) || (!lat && lat!==0) || ! maxDistance) {
    // ...
  }
  Loc.geoNear(point, geoOptions, function(err, results, stats) {
    // ...
  });
};

其中,作者的意思是maxDistance数据是按照公里进行输入,然后转换为弧度,并把弧度作为参数传入geoNear中。但是得到的结果,确实没有任何数据输出。

解决

经过查找后发现,Mongo中对此是如下的定义:

2dsphere Index

If using a 2dsphere index, you can specify either a GeoJSON point or a legacy coordinate pair for the near value.
You must include spherical: true in the syntax.
With spherical: true, if you specify a GeoJSON point, MongoDB uses meters as the unit of measurement:

db.runCommand( {
   geoNear:  ,
   near: { type: "Point" , coordinates: [  ] } ,
   spherical: true,
   ...
} )

With spherical: true, if you specify a legacy coordinate pair, MongoDB
uses radians as the unit of measurement:

db.runCommand( {
   geoNear:  ,
   near: [  ],
   spherical: true,
   ...
} )

书中的源代码确实是GeoJSON的格式,那为何作者使用了弧度,而没有使用米呢?原来Mongoose3.9.5版本才支持了Mongo的这个设置。原文如下:

3.9.5 / 2014-11-10
fixed; geoNear() no longer enforces legacy coordinate pairs - supports GeoJSON #1987 alabid

用可能是作者在写书的时候,还用的OK,后来版本更新后,设置就失效了。

解决

因此,按照作者原来的思路,代码应该改为:

/* GET list of locations */
module.exports.locationsListByDistance = function(req, res) {
    // ...
    var geoOptions = {
        spherical: true,
        maxDistance: maxDistance * 1000,    // <--
        num: 10
    };
    // ...
};

var buildLocationList = function(req, res, results, stats) {
    var locations = [];
    results.forEach(function(doc) {
        locations.push({
            distance: doc.dis / 1000,    // <--
            // ...
        });
    });
    return locations;
};

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/18859.html

相关文章

  • mongodb 提示 no geo indices for geoNear

    { [MongoError: exception: geoNear command failed: { ok: 0.0, errmsg: no geo indices for geoNear }] name: MongoError, message: exception: geoNear command failed: { ok: 0.0, errmsg: no geo indices f...

    lsxiao 评论0 收藏0
  • mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)

    摘要:集合名命名规范集合名不能是空字符串。集合名不能含有字符空字符,这个字符表示集合名的结尾。集合名不能以开头,这是为系统集合保留的前缀。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。 原始文章链接 - 我的博客:http://www.lovebxm.com/2017/0... MongoDB - 简介 官网:https://www.mongodb.com/ ...

    Java3y 评论0 收藏0
  • mongogeo查询

    摘要:不过这样的顺序对于使用弧度查询,很容易出错,即查询要求顺序是经度纬度,即数据和参数都是这样的顺序。对于要指定之类的入参时,使用非要注意单位换算对于使用查询的时候,以及自动设置,无需关心入参单位转换。 maven org.springframework.boot spring-boot-starter-data-mongo...

    Anchorer 评论0 收藏0
  • (转)Mongoose学习参考文档

    摘要:转自一快速通道名词解释一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力由发布生成的模型,具有抽象属性和行为的数据库操作对由创建的实体,他的操作也会影响数据库注意本学习文档采用严格命名方式来区别不同对象,例如的文本属性的数据库模型实 转自 https://cnodejs.org/topic/504... 一、快速通道 1.1 名词解释 Schema : 一种以文件形式存储的...

    Sleepy 评论0 收藏0
  • Nodejs+Express学习二(Mongoose基础了解)

    摘要:学习注定少不了与数据库打交道,而和可以说是绝配,这篇主要是简单介绍这个模块。通过创建查询是数据库中运用最多也是最麻烦的地方,这里对解读的并不完善,仅仅是自己的一点领悟而已。 学习Node注定少不了与数据库打交道,而MongoDB和Node可以说是绝配,这篇主要是简单介绍Mongoose这个模块。由于本人也是边学边写的这篇文章,绝对会有新手的味道,请大神看到这里就表往下看了。 名词介绍稍...

    617035918 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<