暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

mongodb lbs

zhou 2024-07-24
76

LBS:存储每个地点的经纬度坐标,搜寻附近的地点,建立地理位置索引可提高查询效率

地理位置索引

2d :平面 ‘2d’

2dsphere :球面 ‘2dsphere’

查询方式

2d: near:[x,y] geoWithin box矩形 center 圆形 polygon多边形中

2dsphere:geoNear near geoIntersects geoWithin

数据准备
数据格式
 use sample_restaurants;
 //多边形
db.neighborhoods.find();
{
    _id: ObjectId('55cb9c666c522cafdb053a2d'),
    geometry: {
      coordinates: [
        [
          [ -73.96285973961454, 40.61254948646701 ],
          [ -73.9638533251958, 40.61243251871314 ],
          [ -73.96478112808943, 40.61233092216423 ],
          ……
          [ -73.96356470625155, 40.61623872246746 ],
          [ -73.9633609402326, 40.615204428336156 ],
          [ -73.96285973961454, 40.61254948646701 ]
        ]
      ],
      type: 'Polygon'
    },
    name: 'Ocean Parkway South'
  }

Map of a geospatial polygon.

数据下载
wget https://atlas-education.s3.amazonaws.com/sampledata.archive
导入数据
//导入数据
mongorestore --archive=sampledata.archive -u admin -p 'mongodb@123' --port=27017
查看导入数据
show dbs;
admin               180.00 KiB
config               72.00 KiB
local                72.00 KiB
sample_airbnb        52.10 MiB
sample_analytics      9.39 MiB
sample_geospatial   996.00 KiB
sample_guides        40.00 KiB
sample_mflix        108.45 MiB
sample_restaurants    5.61 MiB
sample_supplies     968.00 KiB
sample_training      40.67 MiB
sample_weatherdata    2.39 MiB
test                 11.98 MiB

添加2dsphere索引

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

需要注意的是:mongodb不存在的字段添加索引,但如果GeoJSON 格式不对则会报错:unknown GeoJSON type

要指定 GeoJSON 数据,请使用包含以下内容的嵌入式文档:

  • 一个名为 type 的字段,用于指定 GeoJSON 对象类型,以及

  • 名为 coordinates 的字段,指定对象的坐标。

    <field>: { type: <GeoJSON type> , coordinates: <coordinates> }
    
查找当前邻近区域

可与多边形的边线重叠

查询与经度-73.93414657、纬度 40.82302903位置相交的区域

  db.neighborhoods.findOne(
  { geometry: 
         { $geoIntersects: 
                         { 
                           $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ]} 
                          } 
        }
  }
  )
查找街区中所有的餐厅

位于位置内

var neighborhood = db.neighborhoods.findOne(
 { geometry: 
          { $geoIntersects: 
                       { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] } 
                       } 
            } 
 } 
)
//位于位置内
db.restaurants.find( { location: { $geoWithin: { $geometry: neighborhood.geometry } } } ).count()
按距离查找

即方圆多少以内

centerSphere 的第二个参数接受弧度制的半径(即地球半径英里为单位:赤道半径 3963英里)

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

按从最近到最远的排序顺序返回距离用户五英里范围内的所有餐厅(一英里等于1609.34米)

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

maxDistance单位是弧度, 地球表面1弧度距离约为6378137米, 0.001弧度距离为6378米 } )

db.restaurants.find( { "address.coord" :
                        { $near :
                           [-73.9925306, 40.7309346 ] ,
                            $maxDistance : 0.001
                     } } 
                    ,{"address.coord": 1}
                    )
总结

1.mongodb v2.2以上建议使用2dsphere空间索引

2.需要注意的是:mongodb不存在的字段添加索引,但如果GeoJSON 格式不对则会报错:unknown GeoJSON type

3.GeoJSON 类型有 : Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection

4.2d和2dsphere关于maxDistance的度量完全不一样

2d:maxDistance单位是弧度距离约为6378137米。

2dsphere :maxDistance单位是米

最后修改时间:2024-07-24 01:05:03
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论