视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
MysqlorMongodbLBS快速实现方案
2020-11-09 15:16:59 责编:小采
文档

前两篇文章: 查找附近的xxx 球面距离以及Geohash方案探讨 (http://www.wubiao.info/372) 微信、陌陌 架构方案分析 (http://www.wubiao.info/401) 探讨了,LBS查找附近的XXX;其中包括了,Mysql自定义存储函数方案,以及通过GeoHash、redis自建索引方案

前两篇文章:

查找附近的xxx 球面距离以及Geohash方案探讨 (http://www.wubiao.info/372)

微信、陌陌 架构方案分析 (http://www.wubiao.info/401)

探讨了,LBS查找附近的XXX;其中包括了,Mysql自定义存储函数方案,以及通过GeoHash、redis自建索引方案。

============================================================================================

今天分享两种,利用GeoHash封装成内置数据库函数的简易方案;

A:Mysql 内置函数方案,适合于已有业务,新增加LBS功能,增加经纬度字段方可,避免数据迁移

B:Mongodb 内置函数方案,适合中小型应用,快速实现LBS功能,性能优于A(推荐)

============================================================================================

方案A: (MySQL Spatial)

1、先简历一张表:(MySQL 5.0 以上 仅支持 MyISAM 引擎)

1

2

3

4

5

6

7

8

9

CREATETABLEaddress (

addressCHAR(80)NOTNULL,

address_loc POINT NOTNULL,

PRIMARYKEY(address)

);

空间索引:

1

ALTERTABLEaddress ADDSPATIALINDEX(address_loc);

插入数据:(注:此处Point(纬度,经度) 标准写法)

1

2

3

INSERTINTOaddress VALUES('Foobar street 12', GeomFromText('POINT(30.620076 104.067221)'));

INSERTINTOaddress VALUES('Foobar street 13', GeomFromText('POINT(31.720076 105.167221)'));

查询: 查找(30.620076,104.067221)附近 10 公里

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

SELECT *

FROM address

WHERE MBRContains

(

LineString

(

Point

(

30.620076 + 10 / ( 111.1 / COS(RADIANS(104.067221))),

104.067221 + 10 / 111.1

),

Point

(

30.620076 - 10 / ( 111.1 / COS(RADIANS(104.067221))),

104.067221 - 10 / 111.1

)

),

address_loc

)

============================================================================================

方案B:

1、先建立一张简单的表user,两条数据如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

{

"_id": ObjectId("518b1f1a83ba88ca60000001"),

"account":"simplephp1@163.com",

"gps": [

104.067221,

30.620076

]

}

{

"_id": ObjectId("518b1dae83ba88d660000000"),

"account":"simplephp6@163.com",

"gps": [

104.07958,

30.653936

]

}

其中,gps为二维数组,分别为经度,纬度

(注:此处必须按照(经度,纬度)顺序存储。我们平时表示经纬度,都是(纬度,精度),此处这种方式有木有很亲民)

2、使用之前,先建立二维索引

//建立索引 最大范围在经度-180~180

1

db.user.ensureIndex({"gps":"2d"},{"min":-180,"max":180})

//删除索引

1

db.user.dropIndex({"gps":"2d"})

3、Mongodb有两中方式可以查找附近的XXX;其中方案2)会返回距离(推荐)

1)标准查询,为地球经纬度查询内置;参数一为查询条件利用$near查找附近,参数二$maxDistance为经纬弧度(1° latitude = 111.12 kilometers)即 1/111.12,表示查找附近一公里。

1

db.user.find({ gps :{ $near : [104.065847, 30.6575] , $maxDistance : 1/111.12} })

2)执行命名方式,模拟成一个圆球;参数一指定geoNear方式和表名;参数二坐标,参数三是否为球形,参数四弧度(弧度=弧长/半径 一千米的弧度1000/6378000),参数五指定球形半径(地球半径)

1

db.runCommand({geoNear:'user', near:[104.065847, 30.6575], spherical:true, maxDistance:1000/6378000, distanceMultiplier:6378000});

下载本文
显示全文
专题