MongoDB地理空间索引,如何将它与数组元素一起使用?

时间:2013-10-28 16:12:37

标签: node.js mongodb mongoose geospatial

我想让凯文酒吧位置靠近给定位置。这是userSpots集合:

{   user:'Kevin',
    spots:[
        {   name:'a',
            type:'pub',
            location:[x,y]
        },
        {   name:'b',
            type:'gym',
            location:[v,w]
        }
    ]
},
{   user:'Layla',
    spots:[
        ...
    ]
}

以下是我的尝试:

db.userSpots.findOne(
    {   user: 'Kevin',
        spots: { 
            $elemMatch: {
                location:{ $nearSphere: [lng,lat], $maxDistance: d},
                type: 'pub'
                }
            }
        },
    },
    function(err){...}
)

我收到一个奇怪的错误。 Mongo告诉我在位置字段中没有索引:2d。但是当我用db.userSpots.getIndexes()检查时,2d索引就在那里。为什么mongodb没有看到指数?有什么我做错了吗?

MongoError: can't find special index: 2d for : { spots: { $elemMatch: { type:'pub',location:{ $nearSphere: [lng,lat], $maxDistance: d}}}, user:'Kevin'}

db.userSpots.getIndexes()输出:

    {
    "0" : {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "ns" : "mydb.userSpots",
        "name" : "_id_"
    },
    "1" : {
        "v" : 1,
        "key" : {
            "spots.location" : "2d"
        },
        "ns" : "mydb.usersBoxes",
        "name" : "spots.location_2d",
        "background" : true,
        "safe" : null
    }
}

2 个答案:

答案 0 :(得分:2)

对于类似的地理空间应用,我将位置转换为GeoJSON:

{
    "_id" : ObjectId("5252cbdd9520b8b18ee4b1c3"),
    "name" : "Seattle - Downtown",  
    "location" : {
        "type" : "Point",
        "coordinates" : [
           -122.33145,
            47.60789
         ]
   }
}

(坐标采用经度/纬度格式.Mongo对GeoJSON的使用描述为here。)。

索引是使用:

创建的
db.userSpots.ensureIndex({"location": "2dsphere"})

在我的聚合管道中,我使用以下命令找到匹配项:

{"$match":{"location":{"$geoWithin": {"$centerSphere":[[location.coordinates[0], location.coordinates[1]], radius/3959]}}}}

(其中半径以英里为单位 - 幻数用于转换为弧度)。

答案 1 :(得分:0)

要索引包含地理数据数组的文档,MongoDB使用多键索引。在索引之前,多键索引将文档展开到具有单值而不是数组的某些文档。因此索引将关键字段视为单值字段而不是数组。

尝试不使用$ elemMatch运算符进行查询。