说明:本篇文章介绍地理位置索引。以及介绍 "$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]});
为 shop 集合创建 2D 索引
// 2d不能写成2D
db.shop.createIndex({"loc" : "2d"})
这个时候 shop 集合就可以实现坐标位置的查询了,而要进行查询有两种查询方式:
- "$near" 查询:查询距离某个点最近的坐标点
- "$geoWithin" 查询:查询某个形状内的点
示例:查询坐标为 [11, 11]附近的点
db.shop.find({loc : {"$near" : [11, 11]}})
执行上面的代码会发现数据全部返回了,我们可以设置范围查询,使用 "$maxDistance"。
// "$maxDistance" 最大距离是5(此处为欧式距离)
db.shop.find({loc : {"$near" : [11, 11], "$maxDistance" : 5}})
注意一点,在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]]}}})
范例:查询圆形
db.shop.find({loc : {"$geoWithin" : {"$center" : [[10, 10], 2]}}})
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/