手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜Qcloud , 注册 | 登陆
浏览模式: 标准 | 列表分类:DataBase

关于mongo的GEO相关笔记

很乱。我自己明白即可,三种查询条件。

{loc:{"$near":[121.417397,31.204075]} }
{loc : {"$within" : {"$center" : [ [121.417397,31.204075], 5]}} }
db.places.find({loc:{ $near:[ 30.28009,120.12857],$maxDistance:5}}).limit(20)

上述的内容参考与某个网站,它的基本内容如下:

最近一直在做基于LBS的项目,地标的坐标索引和基于坐标查询,一直没找到一种简单方便的方法,在做mongo索引优化的时发现竟然有Geo的索引
创建字段
建议使用方式:{ loc : [ longitude , latitude] }
也可以:{ loc : { lon :longitude, lat:latitude } }
Loc自己决定,我用poi的
建立索引
注意:每个Collection只能建立一个geospatial索引
db.places.ensureIndex( { loc : “2d” } , { min : -500 , max : 500 } )
如果db.places.ensureIndex( { loc : “2d” }),
默认值的范围是:-180到180,也就是经纬度的范围
查询
注:1.默认会按距离排序;
    2.转换 111.12 距离(一度是大约 111.12 公里)使用公里,或由 69 (对于英里)
默认取100条距离最近的点,注:默认是limit(100)
db.collection.find({loc:{$near :[ 30.28009,120.12857]}})
取正方形范围的坐标点,注意:5是坐标系的5,也就是经纬度的5,按111.12换算成公里
db.places.find({loc:{ $near:[ 30.28009,120.12857],$maxDistance:5}}).limit(20)
取指定半径的点,注意:半径5是坐标系的5,也就是经纬度的5,按111.12换算成公里
以5为半径的圆:{“Coordinate” : {“$within” : {“$center” : [ [30.28009,120.12857], 5]}} }
---------

纯笔记,别多想,测试了一下。比现在使用的好多了,我现在是:
        $criteria->order = new \CDbExpression("ACOS(SIN(({$lat} * 3.1415) / 180 ) *SIN((lat * 3.1415) / 180 ) +COS(({$lat} * 3.1415) / 180 ) * COS((lat * 3.1415) / 180 ) *COS(({$lng} * 3.1415) / 180 - (lng * 3.1415) / 180 ) ) * 6380  asc,last_activity_time DESC");

不要多想,我是用的Yii的玩意,也是一个笔记。

Tags: mongo, geo

mongo中的group by

在mysql里面,我们偶尔会有这样的sql出现:
select userid,count(userid) as cnt from xxxxxtable group by userid;

这样的sql在mongo里怎么实现呢?其实也相对比较简单

PHP代码
  1. <?php  
  2. $mongo = new Mongo();  
  3. $mongo->selectDB('xxx');//库  
  4. $collection = $mongo->selectCollection('表');  
  5.   
  6. $field = array('userid'=>1);  
  7. $cnt = array('cnt'=>0);  
  8. $result = $collection->group($field,$cnt,"function(obj,pref){pref.cnt++;}");  

打印出来的结果也很方便识别:

XML/HTML代码
  1. Array  
  2. (  
  3.     [retval] => Array  
  4.         (  
  5.             [0] => Array  
  6.                 (  
  7.                     [userid] => 11111  
  8.                     [cnt] => 2  
  9.                 ) 
  10.             //省略
  11.         )  
  12.   
  13.     [count] => 21  
  14.     [keys] => 11  
  15.     [ok] => 1  
  16. )  

果然轻轻松松啊

Tags: mongo, mysql

error while loading shared libraries: libaio.so.1

看到这个的时候,觉得不是特别爽:/usr/local/mysql/bin/mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory

然后很纠结,于是想办法解决,其实很容易;

On Debian, if you get the error:

/usr/local/mysql/bin/mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory

type the following

apt-get install libaio1 libaio-dev

On Redhat/Fedora/CentOS:

yum install libaio

redis:Error: read error on connection

在使用redis的时候,出现了Error: read error on connection.
找了一下相关资料,在官方也有很多人提出这个问题
phpredis的作者的意思是,是因为default_socket_timeout的问题,将它设为0就好了.
但很多人都说设为0,在60秒后还是会挂 ,只有设为-1才OK
于是,在命令行下subscribe的时候,先init_set('default_socket_timeout',-1);
问题解决 .

Tags: redis

Mysql数据库索引查询优化的分享

这是昨天SAE分享的一篇文章,开始的时候,我看了一遍,发现好象没有什么特别的内容,但再仔细看的时候,发现居然可以这样做。。。

     问题描述:

      我们要访问的表是一个非常大的表,四千万条记录,id是主键,program_id上建了索引。

      执行一条SQL:

select * from program_access_log where program_id between 1 and 4000

      这条SQL非常慢。我们原以为处理记录太多的原因,所以加了id限制,一次只读五十万条记录

select * from program_access_log where id between 1 and 500000 and program_id between 1 and 4000

      但是这条SQL仍然很慢,速度比上面一条几乎没有提升。Mysql处理50万条记录的表,条件字段还建了索引,这条语句应该是瞬间完成的。

      问题分析:

      这张表大约容量30G,数据库服务器内存16G,无法一次载入。就是这个造成了问题。

      这条SQL有两个条件,ID一到五十万和Program_id一到四千,因为program_id范围小得多,mysql选择它做为主要索引。

      先通过索引文件找出了所有program_id在1到4000范围里所有的id,这个过程非常快。

      接下来要通过这些id找出表里的记录,由于这些id是离散的,所以mysql对这个表的访问不是顺序读取。

      而这个表又非常大,无法一次装入内存,所以每访问一条记录mysql都要重新在磁盘上定位并把附近的记录都载入内存,大量的IO操作导致了速度的下降。

      问题解决方案:

1. 以program_id为条件对表进行分区

2. 分表处理,每张表的大小不超过内存的大小

      然而,服务器用的是mysql5.0,不支持分区,而且这个表是公共表,无法在不影响其它项目的条件下修改表的结构。所以我们采取了第三种办法:

select * from program_access_log where id between 1 and 500000 and program_id between 1 and 15000000

      现在program_id的范围远大于id的范围,id被当做主要索引进行查找,由于id是主键,所以查找的是连续50万条记录,速度和访问一个50万条记录的表基本一样

      总结:

      这是一个在千万笔记录表中由于使用了索引导致了数据查找变慢的问题,有一定的典型性和大家交流下!

-----------

看我标红的那一段,原来还能够这样做,以前真的没有注意过,也从来没有想过,先利用主键做一次过滤。这样效率会好很多啊

上述内容来自:http://ourmysql.com/archives/108?f=wb,该网站还有很多技巧值得一看。

Tags: sae, mysql, 索引

Records:15712345678910»