MongoDB:在$ maxDistance中使用$ near运算符时,不在间隔中

时间:2014-05-28 00:47:36

标签: node.js mongodb geojson

当我试图从Mongo shell找到犹他州盐湖城50公里范围内的所有成员时,我收到错误:

error: {
    "$err" : "point not in interval of [ -180, 180 ] :: caused by :: { 0: 0.0, 1: 50000.0 }",
    "code" : 16433
}

这是我正在运行的查询:

db.members.find(
   { 'geo.point' :
       { $near :
          {
            $geometry : {
               type : "Point" ,
               coordinates : [ 111.000 , 40.000 ]
            },
            $maxDistance : 50000
          }
       }
    }
)

成员架构是这样的:

var memberSchema = mongoose.Schema({
    name: {
        first: {type:String, default:''},
        last: {type:String, default:''},
    },
    geo: {
        latitude: {type:String, default:''},
        longitude: {type:String, default:''},
        country: {type:String, default:''},
        state: {type:String, default:''},
        place: {type:String, default:''},
        zip: {type:String, default:''},
        point: {type: [Number], index: '2d'}
    }
});

DB中的成员对象如下所示:

{
    "_id" : ObjectId("xxxxxxxxxxxxxxxxxxx"),
    "name": {
        "first": "Thom",
        "last": "Allen"
    },
    "geo" : {
        "point" : [ -111.8833, 40.7500 ],
        "zip" : "84115",
        "state" : "UT",
        "country" : "US",
        "longitude" : "-111.8833",
        "latitude" : "40.7500"
    }
}

我的字段可能没有以正确的格式存储吗?如果我将50000更改为低于180的任何值,它将起作用,但这不是它应该如何根据这里的文档运行:

http://docs.mongodb.org/manual/reference/operator/query/near/

**只是抬头,正确的mongo位置数组实际上是[经度,纬度]。

2 个答案:

答案 0 :(得分:2)

一些事情。首先,我认为您的查询已关闭 - 您正在查询坐标:[ 111.000 , 40.000 ],它应该是坐标:[ -111.000 , 40.000 ]

其次,您提供的示例数据点[ -111.8833, 40.7500 ]距离更正的查询点超过50公里,实际上大约为122公里(在此处测试:http://andrew.hedges.name/experiments/haversine/

因此,如果我将数据存储在mongodb中,请更正这两个问题,我可以执行以下操作:

1)创建正确的索引:

db.members.ensureIndex({ "geo.point": "2dsphere" })

2)运行此查询:

db.members.find({ 'geo.point': {$geoWithin: {$centerSphere: [[ -111.000 , 40.000 ], 113/6371]} } } )

请注意,我已经划分了113 km / 6371,它为您提供了这个特定查询所需的弧度。

亲自尝试一下。一般来说,如果你以后可以使用GeoJSON存储东西,但是使用现有的模式和上面的索引和查询,我将能够获得正确的结果。

答案 1 :(得分:1)

您的数据中包含遗留坐标对的格式,但您尝试使用GeoJSON语法进行查询。

传统坐标对的唯一有效索引形式是" 2d" index,所以如果你创建了一个" 2d球体"索引不起作用。所以你需要删除任何" 2d球体"索引并创建一个" 2d"索引如下:

db.members.ensureIndex({ "geo.point": "2d" })

如果你真的打算使用GeoJSON表格和" 2dsphere"索引类型,那么您需要数据来支持它,例如:

 { 
     "loc" : { 
         "type" : "Point",
         "coordinates" : [ 3, 6 ]
     } 
 }

因此它需要"类型"的基础结构。和"坐标"为了使用这个索引类型和查询表单。