首页 > 数据库 >MongoDB CRUD操作:地理位置应用——通过地理空间查询查找餐厅

MongoDB CRUD操作:地理位置应用——通过地理空间查询查找餐厅

时间:2024-06-04 22:05:19浏览次数:15  
标签:geometry MongoDB CRUD geoWithin db 查找 餐厅 查询

MongoDB CRUD操作:地理位置应用——通过地理空间查询查找餐厅

文章目录


MongoDB通过对地理空间建立索引,可以对包含地理空间形状和点的集合上高效地执行空间查询,这边文章介绍了地理空间索引的的基本概念,介绍了地理空间查询的常用方法,演示了 $geoWithin$geoIntersects$nearSphere的使用。

这里以一个App为例,介绍如何来帮助用户查找纽约市的餐厅。App完成的功能有:

  • 使用$geoIntersects查询用户的邻居
  • 使用$geoWithin显示社区的餐厅数量
  • 使用$nearSphere查找用户指定距离内的餐厅

本文将使用2dsphere索引来查询有关球面几何的数据。

地图的扭曲

由于三维球体(例如地球)投影到平面上的原因,在地图上可视化时,球面几何形状会出现一定程度的扭曲。例如,采用由经纬度点 (0,0)、(80,0)、(80,80)和(0,80) 定义的球形正方形的规范。下图描绘了该区域所覆盖的区域:

地图扭曲

搜索餐厅

在进行后续的操作前,需要先准备一些数据,需要先下载邻居neighborhoods餐厅restaurants的集合,并使用下面的命令将其导入数据库:

mongoimport restaurants.json -c=restaurants
mongoimport neighborhoods.json -c=neighborhoods

地理空间索引能在很大程度上提升$geoWithin$geoIntersects的查询性能,下面使用mongosh在对两个集合2dsphere索引:

db.restaurants.createIndex({ location: "2dsphere" })
db.neighborhoods.createIndex({ geometry: "2dsphere" })

浏览数据

查看mongosh中新创建的restaurants集合中的条目:

db.restaurants.findOne()

此查询返回下面的文档:

{
   location: {
      type: "Point",
      coordinates: [-73.856077, 40.848447]
   },
   name: "Morris Park Bake Shop"
}

餐厅对应的位置如下图所示:

餐厅位置

由于使用的是2dsphere索引,因此位置字段中的几何体数据必须遵循GeoJSON格式。

查看邻居neighborhoods集合中的一个条目:

db.neighborhoods.findOne()

查询将返回下面的文档:

{
   geometry: {
      type: "Polygon",
      coordinates: [[
         [ -73.99, 40.75 ],
         ...
         [ -73.98, 40.76 ],
         [ -73.99, 40.75 ]
      ]]
    },
    name: "Hell's Kitchen"
}

数据对应下面的图形显示的区域:

图形区域

查找当前邻居

如果用户的移动设备可以为用户提供准确的位置,那么使用$geoIntersects查找用户当前的邻居就很简单,
假设用户位于经度-73.93414657、纬度40.82302903,要查找当前的邻居,需要使用GeoJSON格式的$geometry 字段指定一个点:

db.neighborhoods.findOne({ geometry: { $geoIntersects: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] } } } })

该查询返回以下结果:

{
    "_id" : ObjectId("55cb9c666c522cafdb053a68"),
    "geometry" : {
        "type" : "Polygon",
        "coordinates" : [
            [
                [
                    -73.93383000695911,
                    40.81949109558767
                ],
                ...
            ]
        ]
    },
    "name" : "Central Harlem North-Polo Grounds"
}

查找附近所有餐厅

要查询给定区域中包含的所有餐厅,可以在mongosh中运行以下命令,可查询出所有餐厅,并计算该社区内的餐厅数量:

var neighborhood = db.neighborhoods.findOne( { geometry: { $geoIntersects: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] } } } } )
db.restaurants.find( { location: { $geoWithin: { $geometry: neighborhood.geometry } } } ).count()

查询显示,在所请求的社区内有127家餐厅,如下图所示:

区域内餐厅

查找一定距离内的餐厅

要查找某个位置指定距离内的餐厅,可以使用$geoWithin$centerSphere返回无序结果,或者使用$nearSphere$maxDistance(如需要按距离排序)。

使用$geoWithin,不排序

要查找圆形区域内的餐厅,可使用$geoWithin$centerSphere$centerSphere是MongoDB特有的语法,通过指定中心和半径(以弧度为单位)来表示圆形区域。

$geoWithin不会按任何特定顺序返回文档,因此它可能会先向用户显示最远的文档。下面的示例查找距离用户5英里以内的所有餐厅:

db.restaurants.find({ location:
   { $geoWithin:
      { $centerSphere: [ [ -73.93414657, 40.82302903 ], 5 / 3963.2 ] } } })

$centerSphere的第二个参数接受以弧度为单位的半径,因此必须除以以英里为单位的地球半径。

使用$nearSphere,排序

也可以使用$nearSphere,并指定以米为单位的$maxDistance(最大距离),将按照从最近到最远的排序方式,返回距离用户5英里范围内的所有餐厅:

var METERS_PER_MILE = 1609.34
db.restaurants.find({ location: { $nearSphere: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] }, $maxDistance: 5 * METERS_PER_MILE } } })

标签:geometry,MongoDB,CRUD,geoWithin,db,查找,餐厅,查询
From: https://blog.csdn.net/superatom01/article/details/139454938

相关文章

  • MongoDB CRUD操作:可重试写入
    MongoDBCRUD操作:可重试写入文章目录MongoDBCRUD操作:可重试写入使用的先决条件部署的限制支持的存储引擎3.6+MongoDB驱动程序MongoDB版本写确认可重试写入和多文档事务启用可重试写入MongoDB驱动mongosh可重试的写操作行为持续的网络错误故障切换周期诊断针对本地......
  • MySQL 查找并删除重复行
    本文讲述如何查找数据库里重复的行。这是初学者十分普遍遇到的问题。方法也很简单。这个问题还可以有其他演变,例如,如何查找“两字段重复的行”(#mysqlIRC频道问到的问题)如何查找重复行第一步是定义什么样的行才是重复行。多数情况下很简单:它们某一列具有相同的值。本文采用这一......
  • 数据结构·查找算法
    查找1.顺序查找一般表(1)代码typedefstruct{ElemType*elem;inttableLen;}SSTable;intsearchSeq(SSTableST,ElemTypekey){ST.elem[e]=key;//设置哨兵for(inti=0;i<ST.tableLen;i++)returni;//存在返回,不存在返回1}(2)设......
  • 数据结构·查找算法
    查找1.顺序查找一般表(1)代码typedefstruct{ElemType*elem;inttableLen;}SSTable;intsearchSeq(SSTableST,ElemTypekey){ST.elem[e]=key;//设置哨兵for(inti=0;i<ST.tableLen;i++)returni;//存在返回,不存在返回1}(2)设......
  • 飞睿uwb定位tag防丢器,蓝牙智能防丢器原理,支持苹果IOS的本地防丢查找
    在当今这个快节奏的社会,人们的注意力经常被各种琐事分散,丢三落四的情况时有发生。随着科技的发展,智能防丢器应运而生,成为帮助我们解决这一烦恼的助手。今天,我们就来深入探讨一款备受瞩目的智能防丢产品——飞睿UWB定位Tag防丢器,它不仅结合了新的蓝牙技术,还拥有自己的APP,支持苹......
  • 浮点数二分查找的实现
            这是C++算法基础-基础算法专栏的第六篇文章,专栏详情请见此处。引入    上次我们学习了整数二分查找的实现,这次我们要学习浮点数二分查找的实现。定义        浮点数二分查找与整数二分查找的定义都是大致相同的,如果想了解具体内容,可以移......
  • 算法第四天力扣第704题:二分查找
    704.二分查找的题目链接如下:https://leetcode.cn/problems/binary-search/https://leetcode.cn/problems/binary-search/  给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 ......
  • 二分查找算法的定义
       二分查找算法,也称为折半查找算法,是一种在有序数组中查找特定元素的常用算法,用于在有序数组或列表中查找特定元素的位置。它的基本思想是:首先确定目标值可能存在的区间,然后逐步缩小区间直到确定目标值的位置或者确定目标值不存在。一、二分查找算法的原理:前提条件:待......
  • Linux -- 环境变量与文件查找
    提示:制作不易看完点个关注和收藏哦前言提示:要解释环境变量,得先明白变量是什么,准确的说应该是Shell变量,所谓变量就是计算机中用于记录一个值(不一定是数值,也可以是字符或字符串)的符号,而这些符号将用于不同的运算处理中。通常变量与值是一对一的关系,可以通过表达式读取它的......
  • OpenCV 的几种查找图像中轮廓边缘的方法
     原始图片: 1、Sobel()Sobel算子结合了高斯平滑和微分,用于计算图像的梯度,从而突出显示边缘。importcv2#读取图像image=cv2.imread('image.png',cv2.IMREAD_GRAYSCALE)#使用Sobel算子查找水平和垂直边缘sobel_x=cv2.Sobel(image,cv2.CV_64F,1,0,ksize......