多边形内的mongoose地理查询

不知何故,我疯了,但让我解释一下。 我有一个文件集合,其中每个文档在“loc”字段中都有一个GPS坐标(下面的示例)。 现在我想查询所有在特定区域的文件。 当我使用MongoShell进行查询时,我得到了正确的结果,但是当我使用Mongoose进行尝试时,每次尝试都失败。

正如你在下面看到的,我尝试了使用2和3 []围绕多边形坐标的不同尝试。

MongoDB版本:2.6.3 Mongoose版本:3.8.13

也许有人可以帮我findtypes或其他一些愚蠢的错误,我没有看到;(可惜的是错误信息“undefined不是一个函数”并没有太大的帮助。

谢谢!

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.失败的Mongoose尝试 ErrorMessage:TypeError:undefined不是一个函数 – 试图把这个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。 错误的Mongoose尝试使用3 [] ** ErrorMessage:MongoError:无法canonicalize查询:BadValue错误的地理查询 – 基于: 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.失败的Mongoose尝试使用2 [] ErrorMessage:TypeError:undefined不是函数基于: https : //github.com/LearnBoost/mongoose/issues/2092和http://mongoosejs.com/docs/api.html #query_Query-内

 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:无法canonicalize查询:BadValue错误的地理查询 – 试图使用一个完整的GeoJSON使用2 []坐标

 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.失败的mongoose尝试 ErrorMessage:TypeError:undefined不是一个函数 – 试图使用一个完整的GeoJSON使用3 []坐标

 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) 

文档中的GeoJSON结构看起来不正确。 尝试以数组forms指定坐标:

  { "_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); });