关于Mongoose的geoNear方法的使用

背景

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

问题

作者在书中演示了通过浏览器的navigator.geolocation发送经纬度坐标到API接口,接着后台使用Mongoose的geoNear方法,从数据库中将离目标坐标较近的数据推送出来。后台从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的格式,那为何作者使用了弧度,而没有使用米呢?原来Mongoose在3.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, //

关键字:mongodb, mongoose, JSON, gps

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部