根据坐标和最大距离查找某个点的最近点 – 使用带有MEAN堆栈的Mongoose查询结果未定义

我有一个问题,我不能解决在一些日子,甚至看相关的堆栈溢出Q / A。

我正在开发一个应用程序,使用苏格兰人艾哈迈德·哈克(Ahmed Haque)的方法创build一个MEAN Stack Google Map应用程序教程 。

我试图实现一个应用程序,使用Google Maps API来绘制坐标包含在存储在MongoDB实例中的GeoJson文件中的PointsLineStringsPolygons

我正在使用Mongoose为我的数据构buildS​​chema并查询我的MongoDB数据库。

我想find最近的点CP给定P0给定P0's latitude and longitude ,给出一个最大的半径distance用于find感兴趣的点。

在这里输入图像描述

给定图像结束后,我想,例如,如果我插入2000(公里),我的查询将find所有的点距离P0最远2000公里。 在这个例子中,它可能应该给我P1和P2。

当我在Mongoose Schema只有Point的时候,我可以做到这一点。

我只有标记(点)有这个Schema

 // Pulls Mongoose dependency for creating schemas var mongoose = require('mongoose'); var Schema = mongoose.Schema; // Creates a User Schema. var MarkerSchema = new Schema({ username: {type: String, required: true}, location: {type: [Number], required: true}, // [Long, Lat] created_at: {type: Date, default: Date.now}, updated_at: {type: Date, default: Date.now} }); // Indexes this schema in 2dsphere format MarkerSchema.index({location: '2dsphere'}); module.exports = mongoose.model('mean-markers', MarkerSchema); 

这是我Old Query for only Markers

 var User = require('./model.js'); app.post('/query/', function(req, res) { // Grab all of the query parameters from the body. var lat = req.body.latitude; var long = req.body.longitude; var distance = req.body.distance; var reqVerified = req.body.reqVerified; // Opens a generic Mongoose Query var query = User.find({}); // ...include filter by Max Distance (converting miles to meters) if (distance) { // Using MongoDB's geospatial querying features query = query.where('location').near({ center: { type: 'Point', coordinates: [long, lat] }, // Converting meters to miles maxDistance: distance * 1609.34, spherical: true }); } }); 

它工作得很好,我能够得到接近点。

然后,我改变了我的Schema更加dynamic,也支持Polylines and Polygons

我可以用下面的Schema插入和绘制新的点,多义线和多边形:

 var mongoose = require('mongoose'); var GeoJSON = require('geojson'); var Schema = mongoose.Schema; // Creates a Location Schema. var LocationSchema = new Schema({ name: {type: String, required: true}, location: { type: {type : String, required: true}, coordinates : [Schema.Types.Mixed] }, created_at: {type: Date, default: Date.now}, updated_at: {type: Date, default: Date.now} }); LocationSchema.index({location: '2dsphere'}); module.exports = mongoose.model('mean-locations', LocationSchema); 

这是我的Mongoose Query

 var GeoObjects = require('./model.js'); app.post('/query/', function(req, res) { // Grab all of the query parameters from the body. var lat = req.body.latitude; var long = req.body.longitude; var distance = req.body.distance; var query; if (distance) { query = GeoObjects.find({'location.type':'Point'}) .where('location.coordinates').near({ center: { type: 'Point', coordinates: [lat, long] }, // Converting meters to miles maxDistance: distance * 1609.34, spherical: true }); } // Execute Query and Return the Query Results query.exec(function(err, users) { if (err) res.send(err); console.log(users); // If no errors, respond with a JSON of all users that meet the criteria res.json(users); }); }); 

console.log(users); 给我undefined.

logging查询结果在我的queryCtrl.js给我以下错误信息:

name: "MongoError", message: "error processing query: ns=MeanMapApp.mean-locatio…ed error: unable to find index for $geoNear query", waitedMS: 0, ok: 0, errmsg: "error processing query: ns=MeanMapApp.mean-locatio…ed error: unable to find index for $geoNear query"

同样有一点变化:

 app.post('/query/', function(req, res) { // Grab all of the query parameters from the body. var lat = req.body.latitude; var long = req.body.longitude; var distance = req.body.distance; console.log(lat,long,distance); var points = GeoObjects.find({'location.type':'Point'}); var loc = parseFloat(points.location.coordinates); console.log(JSON.stringify(loc)); if (distance) { var query = points.near(loc, { center: { type: 'Point', coordinates: [parseFloat(lat), parseFloat(long)] }, // Converting meters to miles maxDistance: distance * 1609.34, spherical: true }); } }); 

这是一个标记的例子:

 { "name": "user01", "location": { "type":"Point", "coordinates": [102.0, 0.0] } } 

近距离运营商如何使用distance和maxDistance:

从苏格兰人使用谷歌地图制作平均应用程序(第二部分)艾哈迈德·哈克

MongoDBsearch参数$ near及其相关属性maxDistance和spherical来指定我们要覆盖的范围。 我们将查询体的距离乘以1609.34,因为我们希望将用户的input(以英里为单位)转换成MongoDB期望的单位(以米为单位)。

  1. 为什么我undefined
  2. 这个问题是否可能是由我的模式造成的?
  3. 我怎样才能解决这个问题?

如果您希望收到一些澄清,只需在下面发表评论。

提前致谢。

我不明白你的代码下面有什么,但我知道一件事情:
如果您正在使用Google的雷达search,则必须考虑到这一点

允许的最大半径是5万米。

只要看看他们的文档

这意味着如果你尝试更高的半径,结果可能是零

我终于设法解决了这个问题。

本质上,这个问题是由模式引起的,因为2dIndex被引用了错误的字段(type and coordinates)

我解决了使用以下架构

 var mongoose = require('mongoose'); var GeoJSON = require('geojson'); var Schema = mongoose.Schema; var geoObjects = new Schema({ name : {type: String}, type: { type: String, enum: [ "Point", "LineString", "Polygon" ] }, coordinates: [Number], created_at: {type: Date, default: Date.now}, updated_at: {type: Date, default: Date.now} }); // Sets the created_at parameter equal to the current time geoObjects.pre('save', function(next){ now = new Date(); this.updated_at = now; if(!this.created_at) { this.created_at = now } next(); }); geoObjects.index({coordinates: '2dsphere'}); module.exports = mongoose.model('geoObjects', geoObjects); 

以下查询

 app.post('/query/', function(req, res) { // Grab all of the query parameters from the body. var lat = req.body.latitude; var long = req.body.longitude; var distance = req.body.distance; var query = GeoObjects.find({'type':'Point'}); // ...include filter by Max Distance if (distance) { // Using MongoDB's geospatial querying features. query = query.where('coordinates').near({ center: { type: 'Point', coordinates: [lat, long] }, // Converting meters to miles maxDistance: distance * 1609.34, spherical: true }); } // Execute Query and Return the Query Results query.exec(function(err, geoObjects) { if (err) res.send(err); // If no errors, respond with a JSON res.json(geoObjects); }); }); 

我希望这会帮助别人!

编辑

我放在架构导致LineStringsPolygons的一些问题。

这里是允许使用geoQueries正确模式

线串-model.js:

 var mongoose = require('mongoose'); var Schema = mongoose.Schema; // Creates a LineString Schema. var linestrings = new Schema({ name: {type: String, required : true}, geo : { type : {type: String, default: "LineString"}, coordinates : Array }, created_at: {type: Date, default: Date.now}, updated_at: {type: Date, default: Date.now} }); // Sets the created_at parameter equal to the current time linestrings.pre('save', function(next){ now = new Date(); this.updated_at = now; if(!this.created_at) { this.created_at = now } next(); }); linestrings.index({geo : '2dsphere'}); module.exports = mongoose.model('linestrings', linestrings); 

多边形model.js

 var mongoose = require('mongoose'); var Schema = mongoose.Schema; // Creates a Polygon Schema. var polygons = new Schema({ name: {type: String, required : true}, geo : { type : {type: String, default: "Polygon"}, coordinates : Array }, created_at: {type: Date, default: Date.now}, updated_at: {type: Date, default: Date.now} }); // Sets the created_at parameter equal to the current time polygons.pre('save', function(next){ now = new Date(); this.updated_at = now; if(!this.created_at) { this.created_at = now } next(); }); polygons.index({geo : '2dsphere'}); module.exports = mongoose.model('polygons', polygons); 

LineString插入

 { "name" : "myLinestring", "geo" : { "type" : "LineString", "coordinates" : [ [ 17.811, 12.634 ], [ 12.039, 18.962 ], [ 15.039, 18.962 ], [ 29.039, 18.962 ] ] } } 

多边形插入:

 { "name" : "Poly", "geo" : { "type" : "Polygon", "coordinates" : [ [ [25.774, -80.190], [18.466, -66.118], [32.321, -64.757], [25.774, -80.190] ] ] } }