一个Mongodb案例-使用地理信息查询酒店

news2024/11/19 23:25:03

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第79篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关注威赞。谢谢。

Mongodb提供了方便的地理位置信息存储和查询方法。并提供了二维平面索引和二维空间索引,来提高查询效率。说到这里,躁动不安想要改变世界的程序员是否就有一些想法了呢?动起我们改变世界的手,创造出来一个又一个基于地图的程序来改变人们的生活。好了,Mongodb的官方人员也有同样的想法,所以直接在官方文档上给出来一个基于地图的使用示例。本文就为你整理介绍官方文档中给出的这个精彩的案例。

概述

mongodb的地理信息索引能够方便快速的让用户查询包含地理信息的集合。包括查询地理信息位置,地理信息覆盖范围查询和计算等。为了展现mongodb在地理信息处理的能力和地理信息不同的处理方法,本文向你介绍了一个编写简单地图应用查询的过程。

本文简单介绍了地理信息索引的概念,然后演示了使用方法$geoWithin, $geoIntersects和$nearSphere查询地理信息。

假设你现在正在研发一个小的地图应用,来帮助客户查找纽约的酒店。这个应用需要具备下面的功能:

  • 使用$geoIntersects确认用户当前街区的地理位置信息。
  • 使用$geoWithin展示该街区的酒店数量
  • 使用$nearSphere查找用户附近几公里内的酒店。

本文使用二维空间索引来查询这些空间信息。

投影畸变

将三维空间投射到平面时,地理信息展现会出现畸变。如将地球投射到平面地图时,就会产生这种畸变。例如,将经纬度范围在四个点(0,0),(80,0),(80,80),(0,80)投射到平面地图时,会出现下图所示的畸变。

地球是个三维球形,从赤道到北极组建变小。所以地球上这四个点围城的区域,投射到平面时,靠近极点的位置,会成为弧形。

酒店查询

数据准备

官网给出两个地址下载两份测试数据集

  • neighborhoods.json

https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/neighborhoods.json

  • restaurants.json

https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/restaurants.json

这两份数据集记录了酒店的位置信息和城市的地理信息。如果下载有困难,用户可以到威赞上传的资源当中去查找。

下载完成这两份数据集后,将这两份数据导入数据库。

mongoimport <path to restaurants.json> -c=restaurants
mongoimport <path to neighborhoods.json> -c=neighborhoods

如果使用命令有困难,也可以使用mongodb compass来import数据。

导入完成后,构建二维空间索引

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

浏览数据

查看一条酒店的信息

db.restaurants.findOne()

返回结果

{
    "_id": {
      "$oid": "55cba2476c522cafdb053add"
    },
    "location": {
      "coordinates": [
        -73.856077,
        40.848447
      ],
      "type": "Point"
    },
    "name": "Morris Park Bake Shop"
  }

地图上显示酒店信息如下

查询一个街区的数据

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)。使用该坐标获取街区信息。

db.neighborhoods.find({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"
}

查找当前街区的所有酒店

前面依据用户的手机获取到了定位信息,查到了用户所在的街区。现在依据用户的所在的街区,查询出该街区所有酒店信息。

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, $centerShpere. 其中$centerSphere方法,是mongodb通过指定点和半径在地理空间内确定圆形的方法。

$geoWithin返回数据并没有排序,因此有可能会将最远的数据放在最前面。

查询附近5营利范围内的酒店

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

其中$centerSphere的第二个参数,接收的是弧度信息。所以要除以地球的半径。

使用$nearSphere查询

用户可以使用$nearSphere和方法$maxDistance组合查询,返回结果按照距离由近到远进行排序。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1867092.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3项目登录成功后根据角色菜单来跳转指定页面(无首页)

前言&#xff1a;需求不想要首页&#xff0c;登录什么角色跳转到这个角色经常使用的页面。&#xff08;例如&#xff1a;审核者角色的人输入用户名密码成功后就自动跳转到待审核的页面&#xff0c;仓库管理员登录成功则自动跳转到仓库列表&#xff09; 需要解决的点和想法&…

Linux笔记之Bash脚本中的EOF

Linux笔记之Bash脚本中的EOF code review! 文章目录 Linux笔记之Bash脚本中的EOF基本用法自定义结束符变量替换禁用变量替换用于脚本嵌入重定向到文件与命令组合总结 在 Bash 脚本中&#xff0c; EOF 通常用于定义一个多行字符串或文档块。这种技术被称为“Here Document”&a…

python基础语法 003-3 数据类型元组

1 元组 1.1 元组含义 1.1.1 元组的表示 #元组的表示方法:() names ("xiaoyun", "xiaoming") print(names)--结果------- (xiaoyun, xiaoming) 1.1.2 空元组 #空元组 names () print(type(names)) print(len(names))----------------结果--------- &l…

802.11漫游流程简单解析与笔记_Part2_02_wpa_supplicant、cfg80211、nl80211内核与驱动的关系

wpa、cfg80211、nl80211内核与驱动的关系示意图如下&#xff1a; nl80211和cfg80211都是内核定义的标准接口&#xff0c;目的是规范驱动和应用的统一调用&#xff0c;wpa中常出现nl80211就是通过内核的nl80211接口调用对应cfg80211的部分&#xff0c;进而控制驱动收发数据或切换…

禁止浏览器对input的自动填充和填充提示(适用于谷歌、火狐、Edge(原IE浏览器)等常见浏览器)

目录 1.要解决的问题2.一技能&#xff1a;原生属性&#xff0c;小试牛刀3.二技能&#xff1a;傀儡input&#xff0c;瞒天过海4.三技能&#xff1a;JavaScript出击&#xff0c;直接开大 写在前面&#xff1a; 如有转载&#xff0c;务必注明出处&#xff0c;否则后果自负。 1.要解…

基于STM32设计的智能家居远程调温系统(通过红外线控制空调)_75

文章目录 一、前言1.1 项目介绍【1】项目功能介绍【2】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置1.3 设计的意义1.4 开发工具的选择1.5 系统框架图1.6 系统功能总结1.7 原理图二、硬件选型2.1 ESP8266-串口WIFI2.2 STM32F103C8T6开发板2.3 红外学…

已解决java.beans.IntrospectionException: 在Java Beans中内省过程失败的正确解决方法,亲测有效!!!

已解决java.beans.IntrospectionException: 在Java Beans中内省过程失败的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 报错原因 解决思路 解决方法 检查命名规范 验证Getter/Setter匹配性 确认访问权限 审查类型一致性 简…

charls抓包工具 mumu模拟器抓包apk

1.先安装mumu 官网添加链接描述 2.配置 设置&#xff0c;点进互联网&#xff0c;点编辑&#xff0c;选择手动代理 主机名写自己电脑的ip地址&#xff0c;端口随便&#xff0c;只要不被占用&#xff0c;一般参考其他人都是8888 3.下载charls 参考这个添加链接描述 先官网…

静态时序分析:ideal_clock、propagated_clock以及generated_clock的关系及其延迟计算规则(一)

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 理想时钟(ideal_clock)、传播时钟(propagated_clock)是两种相对的时钟&#xff0c;理想时钟用于时钟树综合(CTS)前&#xff0c;而传播时钟用于时钟树综合后。生成…

flink-触发器Trigger和移除器Evictor

Trigger 触发器 触发器作用&#xff1a;控制窗口什么时候除法计算。即执行窗口函数&#xff1b;基于WindowStream调用trigger&#xff08;&#xff09;方法&#xff0c;传入自定义触发器&#xff08;trigger&#xff09;&#xff1b; 每一个窗口分配器&#xff08;windowAssi…

Websocket在Java中的实践——握手拦截器

在《Websocket在Java中的实践——最小可行案例》一文中&#xff0c;我们看到如何用最简单的方式实现Websocket通信。本文中&#xff0c;我们将介绍如何在握手前后进行干涉&#xff0c;以定制一些特殊需求。 在《Websocket在Java中的实践——最小可行案例》的基础上&#xff0c;…

工商业储能柜用的Acrel-2000ES储能能量管理系统-安科瑞 蒋静

概述 Acrel-2000ES储能能量管理系统&#xff0c;专门针对工商业储能柜、储能集装箱研发的一款储能EMS&#xff0c;具有完善的储能监控与管理功能,涵盖了储能系统设备(PCS、BMS、电表、消防、空调等)的详细信息&#xff0c;实现了数据采集、数据处理、数据存储、数据查询与分析…

数字化世界的守卫之防火墙

在这个数字化的时代&#xff0c;我们的电脑和手机就像是一座座繁华的城市&#xff0c;而病毒和黑客则是那些潜伏在暗处的敌人。但别担心&#xff0c;我们有一群忠诚的守卫——“防火墙”&#xff0c;它们日夜守护着我们的数字家园。 1. 病毒&#xff1a;数字世界的“瘟疫” 想象…

CNware虚拟化平台功能介绍:虚拟机业务连续性保护,确保核心业务持续运行,构筑稳健的数字防线

全球数字化转型的大潮中&#xff0c;虚拟化技术已成为企业IT架构的基石。据Gartner预测&#xff0c;到2026年&#xff0c;全球90%以上的组织将采用某种形式的虚拟化技术。虚拟化环境的广泛应用&#xff0c;不仅提升了资源利用率、降低了成本&#xff0c;更极大地增强了业务灵活…

PDF转成清晰长图

打开一个宝藏网址在线PDF转换器/处理工具 - 在线工具系列 点击图下所示位置 按照图下所示先上传文件&#xff0c;设置转换参数后点击转换&#xff0c;等待 等待转换完成后&#xff0c;可以在转换结果处选择下载地址&#xff0c;点击即可进行下载使用了。对比了其他几个网站的转…

在Python中使用类继承提高代码复用性使用详解

概要 在面向对象编程(OOP)中,继承是一种创建新类的方式,这些新类继承了一个或多个父类的特性。Python 中的继承允许我们定义保持代码通用性和简洁性的类层次结构。本文将详细探讨 Python 中的类继承机制,包括基本继承、多重继承、方法重写以及使用 super() 函数的技巧,并…

无线幅频仪制作(WiFi通信)-含STM32源程序,JAVA上位机与设计报告

资料下载地址&#xff1a;无线幅频仪制作(WiFi通信)-含STM32源程序,JAVA上位机与设计报告 目录 项目功能 1、 系统方案1.1 比较与选择 1.1.1 控制器的论证与选择 1.1.2 信号源的论证与选择 1.1.3 放大器模块的论证与选择 1.1.4 键盘与显示模块的论证与选择 1.1.5 网络通…

【Spring Cloud Alibaba AI】简单使用

本文基于官方文档。 Spring AI 官方文档&#xff1a;Spring AI :: Spring AI Reference 中文文档&#xff1a;Spring AI 简介 - spring 中文网 (springdoc.cn) Spring AI 是 Spring 官方社区项目&#xff0c;旨在简化 Java AI 应用程序开发&#xff0c;让 Java 开发者像使用…

MySQL进阶——锁

目录 1全局锁—一致性数据备份 1.1全局锁介绍 1.2语法 1.3 一致性备份案例 1.4 全局锁特点 2表级锁 2.1表锁 2.1.1共享读锁 2.1.2独占写锁 2.2元数据锁 2.3元数据锁 MySQL中的锁&#xff0c;按照锁的粒度分&#xff0c;分为以下三类&#xff1a; &#xff08;1&…

DigitalOcean Droplet 云主机新增内置第五代 Xeon CPU 机型

DigitalOcean 近期宣布&#xff0c;在其高级 CPU 服务器&#xff08;Premium CPU-Optimized Droplet&#xff09;队列中引入英特尔第五代Xeon可扩展处理器&#xff08;代号为 Emerald Rapids&#xff09;。作为英特尔产品线中的最新一代用于数据中心工作负载的处理器&#xff0…