多边形内的猫鼬地理查询

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 空间查找多边形内的要素数量(点/线/多边形)

Mongoose 查询返回带有空数组的嵌套文档

Elasticsearch geo搜索奇怪的行为

Sql 2008 查询问题 - 哪个 LatLong 存在于地理多边形中?

如何从实际上在 Postgis 中的多边形内的多边形中获取最近点

在 Cloudant 中使用 MapReduce 获取地理空间索引的结果