多边形内的猫鼬地理查询
Posted
技术标签:
【中文标题】多边形内的猫鼬地理查询【英文标题】:Mongoose Geo-Query within polygon 【发布时间】:2014-09-17 17:20:38 【问题描述】:不知何故我快疯了,但让我解释一下。 我有一个文档集合,其中每个文档在“loc”字段中都有一个 GPS 坐标(下面的示例)。现在我想查询特定区域中的所有文档。 当我使用 MongoShell 进行查询时,我得到了正确的结果,但是当我使用 Mongoose 尝试时,每次尝试都失败了。
正如您在下面看到的,我在多边形坐标周围使用 2 和 3 [] 尝试了不同的尝试。
MongoDB 版本:2.6.3 猫鼬版本:3.8.13
也许有人可以帮我找到我看不到的类型或其他愚蠢的错误;-( 遗憾的是,错误消息“未定义不是函数”并没有太大帮助。
谢谢!
Mongoose 架构
(function ()
module.exports = function (mongoose, Schema)
var PointSchema = new Schema(
_id: Schema.ObjectId,
loc:
type: type: String ,
coordinates: type: [Number]
, collection: "points" );
PointSchema.index( loc: "2dsphere" );
mongoose.model("Point", PointSchema);
;
)();
集合中的示例文档
"_id": ObjectId("53d0d30c92a82799d8ed31d2"),
"loc":
"type": "Point",
"coordinates":
"0": 8.5652166666667,
"1": 49.3288
Mongo-Shell 脚本有效 基于:http://docs.mongodb.org/manual/reference/operator/query/geoWithin/#op._S_geoWithin
db.points.find( loc :
$geoWithin :
$geometry :
type : "Polygon" ,
coordinates : [[[8.594874265234353, 49.33654935186479],
[8.594874265234353, 49.322858939564284],
[8.553675534765603, 49.322858939564284],
[8.553675534765603, 49.33654935186479],
[8.594874265234353, 49.33654935186479]]]
)
1.猫鼬尝试失败 Errormessage: TypeError: undefined is not a function - 试图把shell脚本放到“find”中
var Point = mongoose.model("Point");
var pointFields = '_id': 1, 'loc': 1 ;
Point.find(
loc:
$geoWithin:
$geometry:
type: "Polygon",
coordinates: [[[8.594874265234353, 49.33654935186479],
[8.594874265234353, 49.322858939564284],
[8.553675534765603, 49.322858939564284],
[8.553675534765603, 49.33654935186479],
[8.594874265234353, 49.33654935186479]]]
).select(pointFields).lean().exec(function (error, result)
console.log("Error: " + error);
processResponse(error, result, response);
);
**2。使用 3[] 的 Mongoose 尝试失败 ** Errormessage: MongoError: Can't canonicalize query: BadValue bad geo query - 基于:https://github.com/LearnBoost/mongoose/issues/2092
var geoJsonPoly =
polygon: [[[8.594874265234353, 49.33654935186479],
[8.594874265234353, 49.322858939564284],
[8.553675534765603, 49.322858939564284],
[8.553675534765603, 49.33654935186479],
[8.594874265234353, 49.33654935186479]]]
;
var Point = mongoose.model("Point");
var pointFields = '_id': 1, 'loc': 1 ;
Point.find().where('loc').within(geoJsonPoly).select(pointFields).lean().exec(function (error, result)
console.log("Error: " + error);
processResponse(error, result, response);
);
3。使用 2[] 的 Mongoose 尝试失败 错误消息:TypeError: undefined is not a function 基于:https://github.com/LearnBoost/mongoose/issues/2092 和http://mongoosejs.com/docs/api.html#query_Query-within
var geoJsonPoly =
polygon: [[8.594874265234353, 49.33654935186479],
[8.594874265234353, 49.322858939564284],
[8.553675534765603, 49.322858939564284],
[8.553675534765603, 49.33654935186479],
[8.594874265234353, 49.33654935186479]]
;
var Point = mongoose.model("Point");
var pointFields = '_id': 1, 'loc': 1 ;
Point.find().where('loc').within(geoJsonPoly).select(pointFields).lean().exec(function (error, result)
console.log("Error: " + error);
processResponse(error, result, response);
);
4.Mongoose 尝试失败 Errormessage: MongoError: Can't canonicalize query: BadValue bad geo query - 尝试在坐标周围使用 2[] 来使用完整的 GeoJSON
var geoJsonPoly =
type: "Polygon",
coordinates: [[8.594874265234353, 49.33654935186479],
[8.594874265234353, 49.322858939564284],
[8.553675534765603, 49.322858939564284],
[8.553675534765603, 49.33654935186479],
[8.594874265234353, 49.33654935186479]]
;
var Point = mongoose.model("Point");
var pointFields = '_id': 1, 'loc': 1 ;
Point.find().where('loc').within(geoJsonPoly).select(pointFields).lean().exec(function (error, result)
console.log("Error: " + error);
processResponse(error, result, response);
);
5.猫鼬尝试失败 Errormessage: TypeError: undefined is not a function - 尝试在坐标周围使用 3[] 来使用完整的 GeoJSON
var geoJsonPoly =
type: "Polygon",
coordinates: [[[8.594874265234353, 49.33654935186479],
[8.594874265234353, 49.322858939564284],
[8.553675534765603, 49.322858939564284],
[8.553675534765603, 49.33654935186479],
[8.594874265234353, 49.33654935186479]]]
;
var Point = mongoose.model("Point");
var pointFields = '_id': 1, 'loc': 1 ;
Point.find().where('loc').within(geoJsonPoly).select(pointFields).lean().exec(function (error, result)
console.log("Error: " + error);
processResponse(error, result, response);
);
console.trace() 返回
Trace
at Promise.<anonymous> (C:\Dev\Mobile\src\nodejs\analyze.js:336:17)
at Promise.<anonymous> (C:\Dev\Mobile\src\nodejs\node_modules\mongoose\node_modules\mpromise\lib\promise.js:172:8)
at Promise.EventEmitter.emit (events.js:95:17)
at Promise.emit (C:\Dev\Mobile\src\nodejs\node_modules\mongoose\node_modules\mpromise\lib\promise.js:84:38)
at Promise.reject (C:\Dev\Mobile\src\nodejs\node_modules\mongoose\node_modules\mpromise\lib\promise.js:111:15)
at Promise.error (C:\Dev\Mobile\src\nodejs\node_modules\mongoose\lib\promise.js:89:15)
at Promise.resolve (C:\Dev\Mobile\src\nodejs\node_modules\mongoose\lib\promise.js:107:24)
at Promise.<anonymous> (C:\Dev\Mobile\src\nodejs\node_modules\mongoose\node_modules\mpromise\lib\promise.js:172:8)
at Promise.EventEmitter.emit (events.js:95:17)
at Promise.emit (C:\Dev\Mobile\src\nodejs\node_modules\mongoose\node_modules\mpromise\lib\promise.js:84:38)
【问题讨论】:
【参考方案1】:您文档中的 GeoJSON 结构似乎不正确。尝试将坐标指定为数组:
"_id": ObjectId("53d0d30c92a82799d8ed31d2"),
"loc":
"type": "Point",
"coordinates": [8.5652166666667, 49.3288]
这与您的第五个示例相结合应该可以工作。还可以查看 Point 和 Polygon 上有关其结构的 GeoJSON 参考资料。
工作示例代码:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var PointSchema = new mongoose.Schema(
_id: mongoose.Schema.ObjectId,
loc:
type: type: String ,
coordinates: type: [Number]
, collection: "points" );
PointSchema.index( loc: "2dsphere" );
mongoose.model("Point", PointSchema);
var geoJsonPoly =
type: "Polygon",
coordinates: [
[
[8.594874265234353, 49.33654935186479],
[8.594874265234353, 49.322858939564284],
[8.553675534765603, 49.322858939564284],
[8.553675534765603, 49.33654935186479],
[8.594874265234353, 49.33654935186479]
]
]
;
var Point = mongoose.model("Point");
var pointFields = '_id': 1, 'loc': 1 ;
Point.find().where('loc').within(geoJsonPoly).select(pointFields).lean().exec(function (error, result)
console.log("Error: " + error);
console.log(result);
);
【讨论】:
嗨,对不起,我从 Rockmongo 复制了它,在它的只读视图中显示了一个普通数组。 0: 和 1: 表示数组中的位置。在数据库本身中,它已正确保存。第五个例子对我来说也是最有希望的例子,我也从头开始重写它以避免打字或复制粘贴错误,但仍然没有成功......我只是在问题中更正它 我得到的唯一错误是“TypeError: undefined is not a function”,这就是执行函数 console.log("Error: " + error); 这还是有点模糊。通过_id
进行简单的查找查询时,它是否可以正常工作?我还将用一个简单的示例脚本更新我的答案。
我尝试复制您的工作示例编码,但仍然出现错误。 “错误:TypeError:未定义不是函数”,结果是“未定义”。您使用的是哪个版本的 DB 和 Mongoose,也许我可以尝试使用其他版本。
我在最初的问题中添加了 console.trace 有什么想法吗?以上是关于多边形内的猫鼬地理查询的主要内容,如果未能解决你的问题,请参考以下文章
地理围栏:使用 oracle 空间查找多边形内的要素数量(点/线/多边形)
Sql 2008 查询问题 - 哪个 LatLong 存在于地理多边形中?