MongoDB 地理位置索引

说明:本篇文章介绍地理位置索引。以及介绍 "$near"、"$geoWithin"、"$maxDistance"、runCommand() 的使用。

MongoDB 地理索引

地理信息索引分为两类:2D平面索引,2DSphere球面索引。在2D索引里面基本上能够保存的信息都是坐标,而且坐标保存的就是经纬度坐标。

具体的应用场景在:微信的摇一摇,大众点评等查询附近的住宿地。滴滴、膜拜、OFO等基于位置进行查询的场景都可以使用MongoDB的位置索引。

语法

db.collection.createIndex({field : "2d"})  # 2d不能写成2D

实例

先创建一点数据

# loc表示坐标
db.shop.insert({loc : [10, 10]});
db.shop.insert({loc : [11, 10]});
db.shop.insert({loc : [10, 11]});
db.shop.insert({loc : [12, 15]});
db.shop.insert({loc : [16, 17]});
db.shop.insert({loc : [90, 90]});
db.shop.insert({loc : [150, 160]});

MongoDB 地理位置索引

为 shop 集合创建 2D 索引

// 2d不能写成2D
db.shop.createIndex({"loc" : "2d"})  

MongoDB 地理位置索引

这个时候 shop 集合就可以实现坐标位置的查询了,而要进行查询有两种查询方式:

  • "$near" 查询:查询距离某个点最近的坐标点
  • "$geoWithin" 查询:查询某个形状内的点

示例:查询坐标为 [11, 11]附近的点

db.shop.find({loc : {"$near" : [11, 11]}}) 

MongoDB 地理位置索引

执行上面的代码会发现数据全部返回了,我们可以设置范围查询,使用 "$maxDistance"。

// "$maxDistance" 最大距离是5(此处为欧式距离)
db.shop.find({loc : {"$near" : [11, 11], "$maxDistance" : 5}})

MongoDB 地理位置索引

注意一点,在2D索引里面支持最大距离,但是不支持最小距离。但可以使用"$geoWithin"设置一个查询范围,设置范围如下

// 第一个坐标表示矩形的左边界,第二个坐标表示矩形的右边界
矩形范围($box):{"$box" : [[x1, y1], [x2, y2]]}

// 第一个表示圆心位置,第二个代表半径
圆形范围($center):{"$center" : [[x1, y1], r]}

// 每个数组代表一个坐标点,这些点代表一个多边形
多边形($polygon):{"$polygon" : [[x1, y1], [x2, y2], [x3, y3],...]}

范例:查询矩形

db.shop.find({loc : {"$geoWithin" : {"$box" : [[9, 9], [11, 11]]}}})

MongoDB 地理位置索引

范例:查询圆形

db.shop.find({loc : {"$geoWithin" : {"$center" : [[10, 10], 2]}}})

MongoDB 地理位置索引

runCommand()

在MongoDB里面,除了一些支持操作函数之外,还有一个重要的命令:runCommand(),这个函数可以执行所有的特定的MongoDB命令。

范例:利用runCommand()实现信息查询

db.runCommand({"geoNear" : "shop", near : [10, 10], "$maxDistance" : 5, num : 2})
db.runCommand({"geoNear" : "shop", near : [10, 10], maxDistance : 5, num : 2})
> db.runCommand({"geoNear" : "shop", near : [10, 10], maxDistance : 5, num : 2}

// 返回结果 
{
        "waitedMS" : NumberLong(0),
        "results" : [
                {
                        "dis" : 0,
                        "obj" : {
                                "_id" : ObjectId("5c8f607ebc5b81f4ea1e395e"),
                                "loc" : [
                                        10,
                                        10
                                ]
                        }
                },
                {
                        "dis" : 1,
                        "obj" : {
                                "_id" : ObjectId("5c8f607ebc5b81f4ea1e3960"),
                                "loc" : [
                                        10,
                                        11
                                ]
                        }
                }
        ],
        "stats" : {
                "nscanned" : 33,
                "objectsLoaded" : 3,
                "avgDistance" : 0.5,
                "maxDistance" : 1,
                "time" : 1
        },
        "ok" : 1
}
>

相关返回值说明

  • results中有两个结果,即返回两条数据;
  • "nscanned":33,表示扫描了33条数据;
  • "avgDistance":0.5,表示扫描平均距离0.5;
  • "maxDistance":1,表示最大距离1;
  • "time":11,表示扫描用时11毫秒。

由于本文只是介绍了怎么去使用,下面附上一些连接方便与查看

图解 MongoDB 地理位置索引的实现原理:http://www.cnblogs.com/taoweiji/p/3710495.html

MongoDB 中文社区:http://www.mongoing.com/mongodb-geo-index-1/

 

上一篇:shopAdapter


下一篇:Vue(小案例_vue+axios仿手机app)_Vuex优化购物车功能