当前位置: 首页 > web开发 > PHP > 正文

基于PHP语言的Web开发框架Symfony2详解:结合MongoDB开发LBS应用

时间:2013-09-05 infoq 周攀 洪涛

简介

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

我们将这些技术要点整理成文,希望能够通过本文的介绍和案例,详细 解释如何使用MongoDB进行地理位置信息的查询和处理。在文章的开头,我们也会先介绍一下业界通常用来处理地理位置信 息的一些方案并进行比较,让读者逐步了解使用MongoDB查询及处理地理位置信息的优势。

本文使用了Symfony2和 Doctrine2作为Web应用的开发框架,对于想了解Symfony2的数据库操作的读者来说阅读本文也可以了解和掌握相关的技术和 使用方法。

1. LBS类应用特点

不管是什么LBS应用,一个共同的特点就是:他们的数据都或多或少包含了地 理位置信息。而如何对这些信息进行查询、处理、分析,也就成为了支撑LBS应用的最基础也是最关键的技术问题。

而由于地理位置信息的特殊性,在开发中经常会有比较难以处理的问题出现,比如:由于用户所在位置的不固定性,用户可 能会在很小范围内移动,而此时经纬度值也会随之变化;甚至在同一个位置,通过GPS设备获取到的位置信息也可能不一样 。所以如果通过经纬度去获取周边信息时,就很难像传统数据库那样做查询并进行缓存。

对于这个问题,有读者可 能会说有别的处理方案,没错,比如只按经纬度固定的几位小数点做索引,比如按矩阵将用户划分到某固定小范围的区域( 可以参考后文将会提到的geohash)等方式,虽然可以绕个弯子解决,但或多或少操作起来比较麻烦,也会牺牲一些精度, 甚至无法做到性能的最优化,所以不能算作是最佳的解决办法。

而最近几年,直接支持地理位置操作的数据库层出 不穷,其操作友好、性能高的特性也开始被我们慢慢重视起来,其中的佼佼者当属MongoDB。

MongoDB在地理位置信 息的处理上有什么优势?下面我们通过一个简单的案例来对比一下各种技术方案之间进行进行地理位置信息处理的差异。

2. 几个地理位置信息处理方案的对比和分析

1. 确定功能需求

对于任何LBS应用来说,让用户寻找周 围的好友可能都是一个必不可少的功能,我们就以这个功能为例,来看看各种处理方案之间的差异和区别。

我们假 设有如下功能需求:

显示我附近的人

由近到远排序

显示距离

2. 可能的技术方案

排除一些不通用和难以实现的技术,我们罗列出以下几种方案:

基于MySQL数据库

采用GeoHash索引,基于MySQL

MySQL空间存储(MySQL Spatial Extensions)

使用MongoDB存储地理位置信息

我们一个个来分析这几种方案。

方案1:基于MySQL数据库

MySQL的使用非常简单。对于大部分已经使用 MySQL的网站来说,使用这种方案没有任何迁移和部署成本。

而在MySQL中查询“最近的人”也仅需一条SQL即 可,

SELECT id, ( 6371 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians
( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance
 FROM places HAVING distance < 25 ORDER BY distance LIMIT 0 , 100;

注:这条SQL查询的是在lat,lng这 个坐标附近的目标,并且按距离正序排列,SQL中的distance单位为公里。

但使用SQL语句进行查询的缺点也显而易 见,每条SQL的计算量都会非常大,性能将会是严重的问题。

先别放弃,我们尝试对这条SQL做一些优化。

可 以将圆形区域抽象为正方形,如下图