目录

地理空间查询运算符:

几何操作符说明:

查询操作符说明:

地理空间聚集管道符:

准备工作:

1. mongodb中先插入几条数据:

2. 先给经纬度字段建立2dsphere索引。

地理位置查询案例:

给出一个经纬度,查询mongodb中与其他经纬度的距离

mongodb的查询语句

Java代码实现:

给出经纬度和半径,从mongodb中查询该范围内的所有数

mongodb查询语句

Java代码实现

给出经纬度和半径构建圆形范围,从mongodb中查询是否与其他相交,重叠。

​mongodb实现

java代码实现

多个经纬度构建的几何范围查询

插入测试数据

判断几何图形面积是否相交

mongodb案例:

Java代码实现


  • MongoDB地理空间查询可以解释平面或球体上的几何图形。
  • 2dsphere索引只支持球形查询(即在球形表面上解释几何图形的查询)。
  • 2d索引支持平面查询(即在平面上解释几何图形的查询)和一些球形查询。虽然2d索引支持一些球形查询,但是对这些球形查询使用2d索引可能会导致错误。如果可能,对球形查询使用2dsphere索引。

地理空间查询运算符:

几何操作符说明:

Name Description
$box 使用传统坐标对指定一个用于$geoWithin查询的矩形框 。2D索引支撑 $box。
$center 使用坐标(经纬度)和距离第一 一个圆进行范围查询。2D索引支撑$center。
$centerSphere 在使用球形几何图形时,使用传统坐标或GeoJSON格式指定一个圆来进行$geoWithin查询(在球面上定义一个园,进行范围查询)。2dsphere和 2D索引支持$centerSphere。
$geometry 地理空间几何查询符, 指定GeoJSON格式的类型后。可以配合用以下地理空间查询操作符 $geoWithin,$geoIntersects,$near, $nearSphere。$geometry,进行地理查询.
$maxDistance 指定最大距离以限制$near 和$nearSphere查询的结果。2dsphere和2D索引支持 $maxDistance。
$minDistance 指定最小距离以限制$near 和$nearSphere查询的结果。2dsphere仅与索引一起使用。
$polygon 指定要使用旧式坐标对进行 $geoWithin查询的面。2D索引支撑 $center。
$uniqueDocs 不推荐使用。修改$geoWithin和$near查询以确保即使文档多次匹配查询,查询也会返回一次文档。

查询操作符说明:

$geoIntersects 查询与指定的GeoJSON几何形状相交的几何形状。2dsphere索引支持 $geoIntersects。
$geoWithin 查询与指定的GeoJSON几何重叠的几何。该2dsphere和2D指标支持 $geoWithin。
$near (平面上定圆形,查询该圆形内的数据)返回点附近的地理空间对象。需要地理空间索引。该2dsphere和2D指标支持 $near。
$nearSphere (球面上定圆形,查询该圆形内的数据)返回球体上某个点附近的地理空间对象。需要地理空间索引。该2dsphere和2D指标支持 $nearSphere。

地理空间聚集管道符:

Stage Stage
$geoNear 根据与地理空间点的接近程度返回有序的文档流。为地理空间数据合并了$match、$sort和$limit功能。输出文档包含一个额外的距离字段,并且可以包含一个位置标识符字段。
$geoNear需要一个地理空间索引。

准备工作:

1. mongodb中先插入几条数据:

db.ZHXCDIS.insert({
      "ZXDJDWD" : [  69.3,  89.2 ],    //经纬度
      "BJ" : 10.0,      //半径
      "name": "面馆1"
     })
db.ZHXCDIS.insert({
      "ZXDJDWD" : [  69.4,  89.3 ],   //经纬度
      "BJ" : 20.0,   //半径
      "name": "面馆2"
     })
db.ZHXCDIS.insert({
      "ZXDJDWD" : [  69.5,  89.4 ],    //经纬度
      "BJ" : 30.0,   //半径
      "name": "面馆3"
     })

2. 先给经纬度字段建立2dsphere索引。

▼ 建立索引的字段一定要是数组或者对象,不然创建不了 # 2d不能写成2D

  • 2d索引,用于存储和查找平面上的点。(二维平面)
  • 2dsphere索引,用于存储和查找球面上的点,同时它支持数据存储为GeoJSON 和传统坐标。(查询地球上真实的距离用该索引)

创建索引的例子

  • db.你的Collection名字.createIndex({ 改成你要建立索引的字段名字 : "索引名字" })
  • db.ZHXCDIS.createIndex({ZXDJDWD : "2dsphere"})

地理位置查询案例:

  • 给出一个经纬度,查询mongodb中与其他经纬度的距离

3种距离单位

  • 米(meters)
  • 平面单位(flat units,可以理解为经纬度的“一度” )
  • 弧度(radians) :地球表面1弧度距离约为6378137米, 0.001弧度距离为6378米

 mongodb的查询语句

  • ZHXCDIS是Collection的名字,其他都是固定写法
  • 若需要距离单位为米 则指定 distanceMultiplier: 6378137,
  • 千米 distanceMultiplier: 6378 (不指定该属性,则返回两点相差的弧度)

db.ZHXCDIS.aggregate({
    $geoNear:{
        near:[0,0],         //中括号中写经度纬度
        spherical:true,        //表示使用是否采用球面几何计算 (false则返回平面单位
        distanceMultiplier: 6378137,  //要和spherical:true同时使用,
        distanceField:"distance"    //给返回结果起一个叫distance的别名
        }})

/**
  查询的结果,会根据距离大小自动排序


    "_id" : ObjectId("6204c76ef73f965f1d3e5542"), 
    "ZXDJDWD" : [
        69.3, 
        89.2
    ], 
    "BJ" : 10.0, 
    "name" : "面馆1", 
    "distance" : 5617637.110091394   //相差的距离
}

    "_id" : ObjectId("6204c76ef73f965f1d3e5543"), 
    "ZXDJDWD" : [
        69.4, 
        89.3
    ], 
    "BJ" : 20.0, 
    "name" : "面馆2", 
    "distance" : 5624962.261152434   //相差的距离
}

    "_id" : ObjectId("6204c76ef73f965f1d3e5544"), 
    "ZXDJDWD" : [
        69.5, 
        89.4
    ], 
    "BJ" : 30.0, 
    "name" : "面馆3", 
    "distance" : 5632325.494106238   //相差的距离
}
**/

Java代码实现:

Aggregation aggregation = Aggregation.newAggregation(Aggregation.geoNear(NearQuery.near(ZXDJD, ZXDWD) //经纬度.spherical(true)    //是否采用球面几何计算.distanceMultiplier(6378137D), "distance")); //是别名distance
/*参数一:构造的条件;参数二:表示你要查询mongodb的哪个Collection;参数三:查询的结果封装到实体类*/
List<DisasterOtherDTO> DisasterOtherDTOs = mongoTemplate.aggregate(aggregation, "ZHXCDIS",DisasterOtherDTO.class ).getMappedResults();

点面关系 

  • 给出经纬度和半径,从mongodb中查询该范围内的所有数

mongodb查询语句

//ZHXCDIS是collection的名字,ZXDJDWD是添加了2dsphere的字段,其他固定写法

//查询最远12500米半径,最近200米半径圆形范围内的所有数据

db.ZHXCDIS.find({
     ZXDJDWD:{
     $nearSphere:{
          type: "point",      //指定GeoJson类型为一个点, 
          coordinates: [117.0,39.0]   //经纬度(坐标)
     },
     $maxDistance: 12500,    //最远距离 ,查询坐标12500米内(单位:米)
     $minDistance:200        //最近距离,查询坐标200米外的数据(单位:米)
    }
})

Java代码实现

Point point = new Point(117.0, 39.0);
Query query = new Query(Criteria.where("ZXDJDWD") //经纬度字段.nearSphere(point)    //经纬度.maxDistance(12500d / 6378137d)    //最大距离 (这里一定要除以地球的半径(6378137),得出地弧度).minDistance(200d / 6378137d));    //最近距离 (这里一定要除以地球的半径(6378137))List<DisasterEntity> disasterEntities = mongoTemplate.find(query, DisasterEntity.class);
  • 给出经纬度和半径构建圆形范围,从mongodb中查询是否与其他相交,重叠。

ps:Mongodb中的点面关系,没有直接判断是否相交的功能,只能曲线救国。拿两个圆形范围的半径和,在得到两个圆心的距离,相比即可得出是否相交

逻辑:

  • 计算出经纬度和其他经纬度距离
  • 计算出半径和
  • 筛选出半径和比距离大的数据

mongodb实现

db.getCollection("ZHXCDIS").aggregate([
     {$geoNear:{                  //第一段聚合,先查询出距离,赋值给distance
          near:[69.3,89.2],
          spherical:true,        
          distanceMultiplier: 6378137,  
          distanceField:"distance",
          }},
     {"$addFields":{           //第二段聚合,计算出半径和赋值给num
          "num": {$add:["$BJ",20]}, //这个相当于我们给半径加20,然后将结果赋值给num
     }},
     {                                 
        "$redact": {                //第三阶段,筛选出半径和大于等于距离的数据,证明有相交
            "$cond": [
                { "$gte": [ "$num","$distance"] },    //$num和$distance等同于上面的
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    }
])

//发布博客后格式乱了,看这里

$redact:
  根据字段所处的document结构的级别,对文档进行“修剪”,它通常和“判断语句if-else”结合使用即$cond。 
  $redact可选值有3个: 
   1)$$DESCEND:包含当前document级别的所有fields。当前级别字段的内嵌文档将会被继续检测。 
   2)$$PRUNE:不包含当前文档或者内嵌文档级别的所有字段,不会继续检测此级别的其他字段,即使这些字段的内嵌文档持有相同的访问级别。 
   3)$$KEEP:包含当前文档或内嵌文档级别的所有字段,不再继续检测此级别的其他字段,即使这些字段的内嵌文档中持有不同的访问级别。

java代码实现

 /*** 判断新建灾害现场和未结束的是否相交* @param ZXDJD 经度* @param ZXDWD 维度* @param BJ 半径* @return 返回相交距离最近的数据*/private DisasterOtherDTO crossDisasterRange(Double ZXDJD, Double ZXDWD, Double BJ){//计算出半径和,赋值给num属性ArithmeticOperators.Add add = ArithmeticOperators.Add.valueOf("$BJ").add(BJ);AddFieldsOperation build =Aggregation.addFields().addFieldWithValue("num",add).build();//先查询出距离,赋值给distanceGeoNearOperation distance1 = Aggregation.geoNear(NearQuery.near(ZXDJD,ZXDWD).spherical(true).distanceMultiplier(6378137d)), "distance");//筛选出半径和比距离大的数据,证明有相交Criteria condition = Criteria.where("num").gte("$distance");AggregationExpression conditionExpression = ConditionalOperators.Cond.when(condition).thenValueOf("$$KEEP").otherwise("$$PRUNE");RedactOperation redact = Aggregation.redact(conditionExpression);//管道聚合查询,返回有相交的数据Aggregation aggregation = Aggregation.newAggregation(distance1,build,redact);List<DisasterOtherDTO> results = mongoTemplate.aggregate(aggregation, "ZHXCDIS", DisasterOtherDTO.class).getMappedResults();return results;}

多个经纬度构建的几何范围查询

插入测试数据

ps: 最后的一个经纬度一定要和第一个相同,这样才能闭合

db.demo.insertMany([{
     "name":"测试地点1",
     jw:{       //这是一个geoJson对象
          "type":"Polygon",   // 表示多边形几何
          "coordinates":[[          //结构必须是 [[[经度,维度],[经度,维度]]],三个中括号不可变
            [112.67097473144531,33.338559712732525], //首位必须一样才能闭合
            [112.78495788574217,33.338559712732525],
            [112.78495788574217,33.40679724595547],
            [112.67097473144531,33.40679724595547],
            [112.67097473144531,33.338559712732525]  //首位必须一样才能闭合
          ]]
     }
},{
     "name":"测试地点2",
     jw:{
          "type":"Polygon",
          "coordinates":[[
            [112.79869079589844,33.25476662931654],
            [112.92915344238281,33.25476662931654],
            [112.92915344238281,33.4039312002347],
            [112.79869079589844,33.4039312002347],
            [112.79869079589844,33.25476662931654]
          ]]
     }
},
{
     "name":"测试地点3",
     jw:{
          "type":"Polygon",
          "coordinates":[[
            [112.66273498535156,33.246153192679756],
            [112.7911376953125,33.246153192679756],
            [112.7911376953125,33.31388929028309],
            [112.66273498535156,33.31388929028309],
            [112.66273498535156,33.246153192679756]
          ]]
     }
},
{
     "name":"测试地点4",
     jw:{
          "type":"Polygon",
          "coordinates":[[
            [112.59613037109375,33.34085428063472],
            [112.65380859375,33.34085428063472],
            [112.65380859375,33.40622404437544],
            [112.59613037109375,33.40622404437544],
            [112.59613037109375,33.34085428063472]
          ]]
     }
}
])

db.demo.renameCollection('coordinates')

建索引

db.demo.createIndex(jw.coordinates,"2dsphere")

判断几何图形面积是否相交

mongodb案例:

db.demo.find({
     jw: {   // coordinates是保存经纬度的字段
       $geoIntersects: {   //$geoIntersects: 查询相交的几何形状,$geoWithin:查询重叠
          $geometry: {          // 为地理空间查询运算符指定GeoJSON格式的几何
             type: "Polygon" ,  // 指定GeoJSON格式的几何类型为:Polygon,表示查询多边形
             coordinates: [[     //经纬度构建的多半形,
           [112.76195526123045,33.23064686752627],
           [112.91267395019531,33.23064686752627],
           [112.91267395019531,33.37411872061922],
           [112.76195526123045, 33.37411872061922],
           [112.76195526123045,33.23064686752627]
             ]]
          }
       }
     }
   }
)

注意:

  • 在插入数据的时候coordinates(经纬度)的结构必须是 [[[经度,维度],[经度,维度]]],假如说结构写成[[经度,维度],[经度,维度]],会出现以下的问题。
  • 当你给出经纬度构建一个几何图形,查询相交的时候,必须像图里红色四边形一样,与图中黑色四边形的角(经纬度点)相交才能查询出相交的数据。
  • 如果只是像蓝色四边形一样,与黑色多边形的边相交,mongodb查询不到相交的数据。

Java代码实现

如有问题还请大佬们多多指正

参考:$盒_MonogDB 中文网 (mongodb.net.cn)

mongoDB地理位置查询相关推荐

  1. 七(7)探花功能-MongoDB地理位置查询-附近的人

    课程总结 1.探花功能 业务需求 执行过程 2.MongoDB的地理位置查询 地理位置查询的应用场景 查询案例 3.搜附近 上报地理位置 使用MongoDB搜索附近 一. 探花左划右滑 探花功能是将推 ...

  2. 详解基于MongoDB的地理位置查询,结合Symfony2演示

    简介 随着近几年各类移动终端的迅速普及,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理.我所在的项目也正从事相关系统的开发,我们使用的是S ...

  3. mongdb mysql geospatial 比较_MongoDB的地理位置查询,以及和mysql的使用对比

    MongoDB的一个特色就是具有丰富的查询接口,比如地理位置查询. 在地理位置查询上,MongoDB有着比传统关系型数据库的优势,下面举个例子. 当前移动互联网应用,按用户离目标门店距离排序上的场景很 ...

  4. 23.MongoDB地理位置检索

    MongoDB地理位置检索 一.查询当前坐标附近的目标 @Testpublic void queryNear(){//1.以当前位置的经纬度为圆点GeoJsonPoint point = new Ge ...

  5. MongoDB聚合查询 Pipeline 和 MapReduce

    MongoDB聚合查询 MongoDB聚合查询 什么是聚合查询 Pipeline聚合管道方法 聚合流程 详细流程 聚合语法 常用聚合管道 $count $group $match $unwind $p ...

  6. mongodb模糊查询 php7_详解php7如何实现MongoDB模糊查询

    php7如何实现MongoDB模糊查询?MongoDB模糊查询语句相信对大家来说都不陌生,本文主要给大家介绍了在php 7中MongoDB实现模糊查询的方法,文中给出了详细的介绍和示例代码,对大家具有 ...

  7. MongoDB只查询一个字段

    MongoDB只查询一个字段 db.users.find({}, {"userName":1,"_id":0}) ;1表示取该字段:0不取,因为mongodb默 ...

  8. MongoDB数据库查询性能提高40倍

    MongoDB数据库查询性能提高40倍 大家在使用 MongoDB 的时候有没有碰到过性能问题呢?下面这篇文章主要给大家分享了MongoDB数据库查询性能提高40倍的经历,需要的朋友可以参考借鉴,下面 ...

  9. MongoDB的查询语法和SQL的SELECT语法做对比

    2019独角兽企业重金招聘Python工程师标准>>> 对 数据库的查询是相当频繁的,而且很多特殊的需求我们都可以通过SQL查询语句构造出来.那么我们平时习惯的SELECT语法实现的 ...

  10. java mongodb 模糊查询_Java操作MongoDB插入数据进行模糊查询与in查询功能的方法

    Java操作MongoDB插入数据进行模糊查询与in查询功能 由于需要用MongoDB缓存数据,所以自己写了一套公共的存放和读取方法 具体如下: 存放mongodb: /** * 公共方法:设置Obj ...

最新文章

  1. 深度学习中的贝叶斯统计简介
  2. 理解神经网络,从简单的例子开始(1)7行python代码构建神经网络
  3. 9个value_counts()的小技巧,提高Pandas 数据分析效率
  4. 汉字转拼音(c#) -转载
  5. python进阶(第三章1) 字典
  6. MySQL复制--slave设置读取binlog的位置
  7. UBOOT问题收集(1)--balignl 16, 0xdeadbeef
  8. Impala 调用Hbase 报错 LeaseException
  9. 【BZOJ4025】二分图(可撤销并查集+线段树分治)
  10. 概要设计说明书模板_实验报告的书写案例word模板
  11. 190730每日一句
  12. 33 | 解读TPU:设计和拆解一块ASIC芯片
  13. Windows命令行解决8080端口被占用
  14. 三角形周长最短问题_最短路径问题之三角形的周长最小
  15. 皮特测评:蓝牙耳机哪个品牌最好?300元内最好的蓝牙耳机
  16. 简单的KMeans聚类C++代码实现及解析
  17. 怎么用iTunes备份手机数据 苹果刷机怎么备份手机数据
  18. 平面3连杆机器人正逆解
  19. 第十三章:摄像头接口介绍
  20. 送 5 个 Microsoft Office 账号,拥有48项正版应用含5T空间

热门文章

  1. TPA6100A2DGKR立体声音频功率放大器
  2. luogu1600天天爱跑步
  3. 一题多解×2(流的概念+递归)
  4. 如何快速看懂英文论文?
  5. .mdf数据库恢复mysql_只有mdf文件和ldf文件,怎么恢复数据库。
  6. axure 调整中继器列宽_Axure RP 8教程 - 中继器功能改进
  7. oracle analyze原理,Oracle analyze 介绍
  8. 【高数】高数第五章节——定积分积分上限函数牛顿——莱布尼兹公式反常积分与广义积分
  9. ubuntu流量监控_ubuntu 流量监控
  10. 5G无线增强设计与国际标准 个人整理(PDF和Word)