
MongoDB地理位置索引
在返回结果中的dis字段的值是当前位置与目标位置之间通过两点间距离公式算出来的结果 在两个位置距离相距不是很远的时候,经纬线网可以看出一个平面直角坐标系。但随着距离的增加,地球曲率的影响越来越大,经纬线网就不能再看出平面直角坐标系了。这个时候就要用到2dsphere索引了
在这个例子中我们可以看到2dsphere索引的查询必须要设置spherical: true” 这个参数的设置将两个位置之间的距离换算成米(这里有很多博客或者教程认为是换算成了km,之前我也是这样认为的,但经过实践,单位应当是m),具体如何根据经纬度换算距离大家可以自行百度,我给大家推荐一个根据经纬度算距离的在线工具 根据这个工具再来看实例中的距离,整数部分一致,小数部分略有出入,不过还是可以接受。 以上就是我对MongoDB地理位置索引的一些理解,大家尤其需要注意距离的单位。如有出错的地方,请在下方评论区中指出,阿里嘎多。
发布日期:2021-05-07 10:15:39
浏览次数:20
分类:精选文章
本文共 2512 字,大约阅读时间需要 8 分钟。
相信大家一定都知道微信“附近的门店”这个功能,市面上其他软件也有类似的功能,通过获取当前位置来查找附近一定范围内的某样东西。面对这些需求,mongodb为我们提供了地理位置索引。
在mongodb中,地理位置索引的概念是将一些点(其实也不仅仅是点,后面会提到)的位置储存在mongodb中,创建索引后,可以按照位置进行查询。 mongodb地理位置索引分为2d索引与2dsphere索引。前者用于储存和查找平面上的点,后者用于储存和查找球面上的点。下面将为大家详细讲解这两种地理位置索引。2d索引
创建方式:db.集合名.ensureIndex({key:”2d”}) 举个栗子,我们先在数据库中插入几个地点的数据db.imooc_collection.insert({ name:"圆明园",pos:[90,70]})db.imooc_collection.insert({ name:"故宫",pos:[100,80]})db.imooc_collection.insert({ name:"卢浮宫",pos:[90,30]})
这里需要注意的是,表示坐标的pos的值是一个数组,包含两个值,分别代表经度和维度,经度[-180,180],维度[-90,90]。在插入时,如果经度超过范围会会提示错误,而维度却不会,但查询的时候会发生“不可预期的错误”。
那么我们在插入数据并且建立好索引之后,就可以开始查询数据了。查询的方式有三种,分别是near、geoWithin、geoNear naer查询db.集合名.find({ pos:{$near:[经度,维度]}})
如果我们直接像这样子进行查询,结果会按照离目标坐标的远近输出数据库中存储的100个位置信息,所以,要精确查找距离目标坐标一定范围内的位置,则需要$maxDistance的帮助。所以,我们可以把上面的代码修改为下面这样子
db.集合名.find({ pos:{$near:[经度,维度],$maxDistance:10}})
这样,就只显示距离目标坐标半径10以内的位置。
那么,一个关键的问题来了maxDistance中数值的单位是什么? 接下来的一些其他的参数的单位也会涉及到这个问题。这些数值的单位是公里还是米? 正如之前所说,2d索引用于储存和查找平面上的点,虽然其坐标的取值被限制在现实世界中经纬度的取值范围内,但事实上,我们应该理解这些使用2d索引的点其实都在一个平面直角坐标系上。这个坐标系的x轴取值范围为[-180,180],y轴取值范围为[-90,90],所谓的Distancs其实就是按照平面坐标系上两点的距离公式计算出来的。mongodb从3.0.0版本开始支持minDistance geoWithin查询 该查询方式用于查询某个形状内的点,形状主要有矩形、圆形、多边形三种,分别表示如下 db.集合名.find({pos:{ $geoWithin:{ $box:[[0,0],[3,3]]}}}) 矩形,box的两个值分别代表矩形左上角与右下角的坐标db.集合名.find({pos:{
$geoWithin:{ $center:[[0,0],r]}}}) 圆形,center的两个值分别代表圆心的坐标与半径db.集合名.find({pos:{
$geoWithin:{ $polygon:[[0,0],[3,3],[4,4],……]}}}) 矩形,polygon的值代表多边形各个顶点的坐标geoNear查询
geoNear查询使用runCommand命令进行使用db.runCommand({ geoNear:集合名字符串, near:坐标数组, minDistance:最小距离,可选 maxDistance:最多距离,可选 num:限制返回结果的数目)}
我们来看一个实例
2dsphere索引
创建方式:db.集合名.ensureIndex({pos:”2dsphere”}) 需要注意的是,在2dsphere索引中,位置的表示方式不再以[经度,维度]来表示,其表示方式叫做GeoJSON GeoJSON的写法为:{type:”Point/LineString/Polygon”,coordinates:[经度,维度]} 其中type字段表示当前坐标是一个点的坐标还是一条线或者一个多边形的;coordinates字段则表示当前位置的坐标——如果是一个点,那就是该点的经度维度、如果是一条线,则是线起点与终点的坐标、如果是多边形,则是多边形各个顶点的坐标。需要注意的是,使用2dsphere索引的数据中必须有GeoJSON字段,比如:db.imooc_collection.insert({ name:"金字塔",pos:{type:"point",coordinates:[105,41]}})
pos字段就是一个GeoJSON数据。2dsphere的查询方式与2d一样,我们将之前圆明园、故宫、卢浮宫的数据换成GeoJSON形式进行一次查找
发表评论
最新留言
做的很好,不错不错
[***.243.131.199]2025年04月03日 23时55分02秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
蓝桥杯 历届试题 幸运数 (堆+DFS)
2021-05-08
微信js-sdk使用简述(分享,扫码功能等)
2021-05-08
selenium 的介绍和爬取 jd数据
2021-05-08
【分享-一键在线抠图】在线免费去除图片背景
2021-05-08
layui表格checkbox选择全选样式及功能
2021-05-08
mxsrvs支持thinkphp3.2伪静态
2021-05-08
mui HTML5 plus 下载文件
2021-05-08
环信SDK 踩坑记webIM篇(一)
2021-05-08
通信基础知识
2021-05-08
DSP开发板准备
2021-05-08
测试基本
2021-05-08
c++中istringstream及ostringstream超详细说明
2021-05-08
c++中ifstream及ofstream超详细说明
2021-05-08
c++中explicit和mutable关键字探究
2021-05-08
c语言结构体字节对齐详解
2021-05-08
linux c/c++面试知识点整理(八)
2021-05-08
linux网络编程系列(十二)--滑动窗口、拥塞控制、断线重连机制
2021-05-08
Deep residual learning for image recognition
2021-05-08
IO控制器
2021-05-08