zoukankan      html  css  js  c++  java
  • 如何获得最近的餐馆谁

    工作前,老板给的曲目标题。是最近LBS要求。

    为了让您的当前位置最近的一些餐厅。

    已有的一些:数据库里大概存着一百万个餐厅的具体记录。包含id,name和经纬度等。

    移动端给你返回他当前的经纬度,让你找出附近的餐厅。


    大概试了下。假设直接查数据库。事实上也不慢,在经纬度都加索引的情况下,模糊查询(比方client返回的经纬度是38.1024和62.2048),既然是附近你就按38.102-------38.103 和62.204------62.205查。仅仅要经纬度符合这俩区间就算是附近的餐厅。

    SQL:

    select id,name from tablename where jingdu>38.102 and jingdu<38.103 and weidu>62.204 and weidu<62.205;


    运行时间,经纬度不加索引的话 100万条记录大概是0.3秒,加了索引大概0.06秒。已经算挺快了。

    可是我们站点日PV 3KW,移动端很多其它,假设每次都这样就把数据库跑死了。可是假设存缓存。又不太合适。毕竟不能为每一个人都存一组他们附近餐厅的缓存,不科学。

    所以要用到缓存。

    下面是我的方法:


    client传来经度和纬度。我们先模糊化,依据我在百度地图上查到的数据分析,经纬度在小数点第三位的时候,大概距离是80米,符合“附近”。第四位四舍五入(比方我们能够觉得经度38.2356的模糊经度为38.236)

    所以。当client传给我们一个经纬度为  38.1024,69.2048 时,我们先四舍五入后得到 38.102,69.205 这个模糊经纬度,然后依据经纬度哈希值,能够用md5啊类似的之类进行hash,得到的值为key,用redis的hget方法来取

    $redis->hget('nearest',$key);

    假设没取到。则去mysql里进行查找

    select id,name,jingdu,weidu from tablename where ROUND(jingdu,3) = 38.102 and ROUND(weidu,3)=69.205


    得到的数据以array存入redis的哈希表,并返回这些数据。

    这样下次再有人在这附近查附近的餐厅。就能够直接从redis的哈希表里取出了


    以上这样的方法不必考虑原始数据的问题,不必跑一遍全部数据把他们都放redis里。而是用到哪里的餐厅找哪里,一次查找终生受用。以后再增加新餐厅的话。直接模糊餐厅经纬度,然后放入redis的hash表里供后面的查阅。


    另一种方法,就仅仅说说思路吧。

    是基于geohash算法的思路。尽管geohash是专门对经纬度进行哈希的算法,可是他更适用于地图。而不适用于餐厅。他是把地图分为若干个大矩形来存key,每一个矩形分为若干个小矩形来存key,然后依据client传来的经纬度,先匹配大矩形,再匹配小矩形,来查找餐厅。刚開始切割地图的时候成本太高,而且效率太低,占资源(内存)还无用。由于我们的主要数据是这一百多万餐厅,并不是一百多万城市。有些城市可能东南角有一大片餐厅。而西北角一家都没有,如果依照geohash的思路,就要维护东南角和西北角两个key了(如果他俩离得非常远)。

    而西北角的key根本无东西。

    所以我们採取了第一种方法,一个区域查的人越多越高效。

    当然。为了提高准确性和精度,我们能够在外层或内层再加一层数据,加外层,意思就是先查外层,精确到小数点后两位,先查大区域内的餐厅。再查小区域内的餐厅。多了层key,多占用了很多其它些的内存,只是这样先查大区域是为了避免小区域内真的没餐厅。


    大体思路就是这样


    client传来(38.1234,68.5678) 模糊hash    md5(38.123_68.568),得到key后    redis->hget('nearest',$key)

    没有就查数据库

    并生成array插入hash表,有就直接返回餐厅name和id


    涉世未深,假设本文有哪些不足或者错误还请各位大牛指正


    ================================补充

    如今非常多client获取近期餐厅的时候,还须要获取这个餐厅在他的哪个方向。还有距离多远,假设用上面我的方法是无法获取的,只是能够在上面的sql里,在查餐厅id和name的时候加上再查经纬度,一并保存在hash表里,这样在娶到近期餐厅们后,就能够依据client传来的精确的经纬度,和查到的这些餐厅本身的精确经纬度,来求出餐厅距离本人当前的方向和距离了(大众点评client有这个功能)


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    python zip,lambda,map函数
    TKinter Scale
    TKinter Radiobutton
    TKinter Listbox
    TKinter Entry 和 Text
    TKinter Label 和 Button
    python中global的用法
    收不到github认证邮件
    IDEA中文显示字体混乱
    使用码云加速下载github项目
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4820889.html
Copyright © 2011-2022 走看看