在给定坐标和最大距离的情况下查找到某个点的最近点 - 使用 Mongoose 和 MEAN 堆栈查询结果未定义
Posted
技术标签:
【中文标题】在给定坐标和最大距离的情况下查找到某个点的最近点 - 使用 Mongoose 和 MEAN 堆栈查询结果未定义【英文标题】:Finding Closest Points to a certain Point Given its Coordinates and Maximum Distance - Query Result Undefined using Mongoose with MEAN Stack 【发布时间】:2016-10-10 12:34:21 【问题描述】:我有一个问题在几天内都无法解决,即使查看相关的 Stack Overflow Q/A。
我正在开发一个重用 Scotch's Create a MEAN Stack Google Map App Tutorial by Ahmed Haque 方法的应用程序。
我正在尝试实现一个使用 Google Maps API 绘制 Points
、LineStrings
和 Polygons
的应用程序,这些坐标包含在 GeoJson 文件中存储在 MongoDB 实例中。
我正在使用Mongoose
为我的数据构建架构并查询我的MongoDB
数据库。
我想找到最接近某个点
CP
的点P0
给定P0's latitude and longitude
并给定最大半径distance
用于查找感兴趣的点。
鉴于图像结束,我希望这样,例如,如果我插入 2000(公里),我的查询将找到距离 P0 最大 2000 公里的所有点。在这个例子中,它可能应该给我 P1 和 P2。
当我的Mongoose Schema
中只有积分时,我能够做到这一点。
我有这个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
更改为更具动态性并支持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.
在我的 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]
$near 运算符如何处理距离和 maxDistance:
来自Scotch's Making MEAN Apps with Google Maps (Part II) by Ahmed Haque
MongoDB 搜索参数 $near 及其相关属性 maxDistance 和球面来指定我们要覆盖的范围。 我们将查询主体的距离乘以 1609.34,因为 我们想要获取用户的输入(以英里为单位)并将其转换为 MongoDB 期望的单位(以米为单位)。
-
为什么我会收到
undefined
?
这个问题有可能是我的 Schema 引起的吗?
我该如何解决这个问题?
如果您想获得一些澄清,请在下面发表评论。
提前致谢。
【问题讨论】:
嘿@AndreaM16。你有没有机会在 GitHub 或其他地方有此代码,以便我们将其拉下来仔细查看? 嗨,艾哈迈德,你看了吗? 【参考方案1】:我不明白你所有的代码下面是什么,但我知道一件事: 如果您使用 Google 的雷达搜索,则必须考虑到
最大允许半径为 50 000 米。
看看他们的Documentation
意味着如果您尝试使用更大的半径,结果可能为零
【讨论】:
您好,非常感谢您的回答。我没有使用谷歌的雷达搜索,我正在尝试使用 MongoDb 的 near 和 geoNear 运算符。事实是,正如我在上面所写的,当我有一个不同的 Mongoose 模式(只有标记)时,我的查询可以正常工作。 MongoDB 搜索参数 $near 及其相关属性 maxDistance 和spherical 来指定我们要覆盖的范围。我们将查询主体的距离乘以 1609.34,因为我们希望获取用户的输入(以英里为单位)并将其转换为 MongoDB 期望的单位(以米为单位)。 关于您的console.log(users)
行,一旦我遇到类似问题。问题是 JS 的非阻塞特性,它执行日志比响应更快。就我而言,承诺或回调解决了这个问题。你试过这种方法吗?
是的,我已经尝试过了,但它总是不确定。我认为这个问题是由我的新模式和 near 运算符引起的。【参考方案2】:
我终于设法解决了这个问题。
本质上,问题是由架构引起的,因为 2dIndex
被引用到错误的字段 (type and coordinates)
。
我使用以下 Schema 解决了:
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);
);
);
希望对大家有所帮助!
编辑
我放置的架构导致LineStrings
和Polygons
出现一些问题。
这里是允许使用geoQueries
的正确模式
linestring-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);
多边形模型.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);
线串插入:
"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]
]
]
【讨论】:
以上是关于在给定坐标和最大距离的情况下查找到某个点的最近点 - 使用 Mongoose 和 MEAN 堆栈查询结果未定义的主要内容,如果未能解决你的问题,请参考以下文章