app后端设计(6)-- LBS
在LBS的应用中,一个基本的需求是查找附近的用户,现在有两种做法:
1. 使用mysql的空间数据库,具体做法参考:http://blog.sina.com.cn/s/blog_a48af8c001018q1p.html 。
2. 使用geohash编码,这个是本文需要讨论的。
geohash编码,可以把球面上的经纬度转换成一个值,简单点来说就是把二维坐标转换成一维坐标。查找附近的时候,非常方便,用SQL中,LIKE ‘w23yr3%’可查询附近的所有地点。
geohash的详细介绍,可参考 http://www.wubiao.info/372
在以前的产品中,一个需求是查找用户附近的商铺,发现用mysql LIKE ‘w23yr3%’这种方式检索geohash性能上的瓶颈很大,检索130万行的数据,平均花费了8秒,这是响应速度是无法忍受的。
后来经过不断优化,确定了如下使用coreseek+redis+mysql解决方案,一下子就把响应速度减少到平均1 秒,这个方案的如下:
1. 用每个商铺的坐标值计算geohash,把geohash作为key,商铺的作为value,放到redis的set集中。
$this->cache->redis->select(1);//不能使用0,因为这里有大量的数据,需要独立
$this->cache->redis->set('place:geohash:'.$geohash,$place_id);
2. 根据用户的坐标,在redis中查找附近的商铺id
<?php
    /**
     * 获取附近的地标公共处理方法
     * @param $lat
     * @param $lng
     * @param $n geohash值的长度,一般来说,当n=6,是获取当前附近1千米范围内的用户
     */
    function getLocalPlace($lat, $lng, $n)
    {
        $lat = (float) $lat;
        $lng = (float) $lng;
        $nowGeohash = $this->geohash->encode($lng, $lat);
        $likeGeohash = substr($nowGeohash, 0, $n);
        $placeIds = array();
		$this->_loadDriver('cache', array('adapter' => 'redis'));
		//不能使用0,因为这里有大量的数据,需要独立
		$this->cache->redis->select(1);
		//*表示模糊匹配,例如有key werewfs,werewfw,那么使用“werewf*”,则能同时匹配werewfs,werewfw
		$geohashKeys = $this->cache->redis->keys('place:geohash:' . $likeGeohash . '*');
		$hashlen = strlen($nowGeohash);
		if ($geohashKeys)
		{
			$searchKeys = array();
			//对坐标进行排序
			foreach ($geohashKeys as $k => $v) {
				$v = ltrim($v, 'place:geohash:');
				for ($i = $n; $i < $hashlen; $i++) {
					$compare_hash = substr($nowGeohash, 0, $i);
					$cur_hash = substr($v, 0, $i);
					if ($compare_hash != $cur_hash)
					{
						$nofst = str_pad(($i - 1) . $k, 6, '0');
						$searchKeys[$nofst] = 'place:geohash:' . $v;
						break 1;
					}
				}
			}
			if ($searchKeys)
			{
				krsort($searchKeys);
				//mget表示返回所有特殊keys的values
				$placeIds = $this->cache->redis->mget($searchKeys);
			}
		}
		return $placeIds;
    }
3. 如果需要查找关键字或商铺的类型,则用把2中$placeIds 作为filter调戏 ,在coreseek中继续查找。
如果您觉得这系列的文章对你有所帮助,欢迎打赏。
支付宝账号:190678908@qq.com 收款人:曾健生
[文章作者]曾健生
[作者邮箱]h6k65@126.com
[作者QQ]190678908
[新浪微博] @newjueqi
[博客]http://blog.csdn.net/newjueqi
http://blog.sina.com.cn/h6k65
版权声明:本文为博主原创文章,未经博主允许不得转载。
app后端设计(6)-- LBS的更多相关文章
- app后端设计(14)--LBS的偏移问题
		刚开始做LBS的时候,有一个问题,通过手机获取的坐标,放到百度地图或高德地图上,总是会出现偏移,例如,当时是在微信的前总部"南方通讯大厦"附近获取的坐标,那是把坐标放到百度地图上却 ... 
- app后端设计--总目录 (转)
		特此说明,我转载的!!! app后端设计(1)--api app后端设计(2)--xmpp的使用 app后端设计(3)--短信,邮件,推送服务 app后端设计(4)-- 通讯的安全性 app后端设计( ... 
- app后端设计--总目录
		做了3年app相关的系统架构,api设计,先后在3个创业公司中工作,经历过手机网页端,android客户端,iphone客户端,现就职于app云后端平台bmob(想了解bmob点击这里).其中的乐与苦 ... 
- app后端设计(0)--总文件夹
		原文:http://blog.csdn.net/newjueqi/article/details/19003775 做了接近两年app相关的系统架构,api设计,先后在两个创业公司中工作,经历过手机网 ... 
- [置顶] app后端设计--总目录
		版权声明:本文为博主原创文章,未经博主允许不得转载. 做了3年app相关的系统架构,api设计,先后在3个创业公司中工作,经历过手机网页端,Android客户端,iphone客户端,现就职于app云后 ... 
- app后端设计(0)--总目录(转)
		原文:http://blog.csdn.net/newjueqi/article/details/19003775 做了接近两年app相关的系统架构,api设计,先后在两个创业公司中工作,经历过手机网 ... 
- app后端设计(php)
		来源:http://blog.csdn.net/column/details/mobilebackend.html?page=1 做了3年app相关的系统架构,api设计,先后在3个创业公司中工作,经 ... 
- app后端设计(12)--图片的处理
		app上线后,不断接受用户的反馈,于是,反馈非常差的情况下,都会有app的改版. 一旦app的改版,都会有比较大的UI改动,一改动UI,那么图片的尺寸也就必须要改变. 在app后端设计(1)—api( ... 
- app后端设计(11)-- 系统架构(2014.12.05更新)
		个人认为,在小型的创业团队中,特别是以应用产品为主,在架构后台的时候,需要集中精力解决自身业务上的问题,不是花时间解决第三方已经解决的问题,简单点来说,就是能用第三方服务就使用第三方的服务.基于这个原 ... 
随机推荐
- PS 图像调整算法——黑白
			这个算法是参考自 阿发伯 的博客: http://blog.csdn.net/maozefa 黑白调整 Photoshop CS的图像黑白调整功能,是通过对红.黄.绿.青.蓝和洋红等6种颜色的比例调节 ... 
- 苹果新的编程语言 Swift 语言进阶(十五)--协议
			协议定义了适合某个特定任务或功能需要的方法.属性和其它需求的一个蓝图.协议本身不提供这些需求的实现,它只是描述了一个任务或功能实现的蓝图. 协议与java 语言中的接口定义类似,都是描述了一个实现可以 ... 
- The 16th tip of DB Query Analyzer
			The 16th tip of DB Query Analyzer ---- SQL Schedule will be executed even DBMS h ... 
- iOS中动态计算不同颜色、字体的文字高度
			在改项目bug的时候,有一个问题动态计算label的高度,前开发者竟然用字符串长度除以14.16这样的常量来计算是否换行,结果cell的高度问题非常严重. 因为label内容里有部分关键字是要另一种颜 ... 
- git push 小结
			$ git push ssh://git@dev.lemote.com/rt4ls.git master // 把本地仓库提交到远程仓库的master分支中 $ git remote add orig ... 
- 关于getch()函数
			从百度上得知: 这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车,有的C语言命令行程序会用到此函数做游戏,但是这个函数并非标准函数,要注意移植性! 所以有这样的一个接口,那就很 ... 
- IT小团队的管理者的突围之道
			笔者前几天被问到一个问题,你在团队管理方面有什么值得分享的吗?咋一听,实用千言万语,但是事后回忆说出来的东西感觉空无一物,缺少干货.故想通过写一篇随笔思考整理一下,刷新一下自己对小团队管理的认知.这里 ... 
- 关于mybatis更新数据的问题
			前两天用mybatis的时候,发现这样一个问题,日志显示mytatis更新数据已经成功了,但是实际上数据库是没有更新到的,经过一番查找,发现mybatis更新的时候默认返回的是查找到的数据(Rows ... 
- DHCP的主要知识点
			首先,先写一遍配置 好几种安装方式,我这里用的最简单的yum源安装: mkdir /mnt/cdrom mount -r /dev/sr0 /mnt/cdrom ##创建挂载点 vim / ... 
- Mybatis 系列9
			上篇系列8中 简单介绍了mybatis的查询,至此,CRUD都已讲完. 本文将介绍mybatis强大的动态SQL. 那么,问题来了: 什么是动态SQL? 动态SQL有什么作用? 传统的使用JDBC的方 ... 
