lbs纯真ip库集成笔记

2012-05-09 14:37  2635人阅读  评论 (0)
Tags: ip

要做LBS,网站应用需要,调用别人的API速度太慢,还不一定成功,干脆自己来一个.在这里只说说原理,就不副代码了,因为这种复杂系统的代码直接拿来多半是不能用的.呵呵.

先去纯真官网下载纯真ip库,然后导出,替换掉连七八糟的东西.

// 其中一条
117.82.102.0    117.82.213.255  江苏省苏州市 电信

然后导入到mongo数据库里边,当然mysql也适用.mongo文档格式为:

{
    "_id" : ObjectId("4faa0eb2e0ee3b1b0208a119"),// 不解释
    "ip1" : 1968334336, // ip范围开始,
    "ip2" : 1968363007, // ip范围结束
    "addr" : "江苏省苏州市" // 地区
}

 

其中ip1是ip2long(117.80.0.0)的结果,ip2是ip2long(117.80.20.80)

比如查询ip 117.82.160.97

// php code
$ip = ip2long('117.82.160.97');
$db->ip->findOne(array('ip1'=>array('$lte'=>$ip), 'ip2'=>array('$gte'=>$ip)));

 

然后用字符匹配方式匹配出省和市,这样就ok了

但是测试了以后,将近44万的数据,查询起来真的好慢.通过explain分析可以看出没有索引是全集合扫描,扫描了439288个文档,建立了索引以后,扫描了394583个文档,都不是很理想.并且建立索引以后时间比没有索引时间还要多,1683-303=1380,多了1秒多...无语

> db.ip.count()
439288
> db.ip.find({ip1:{$lte:1968177160}, ip2:{$gte:1968177160}}).explain()
{
    "cursor" : "BasicCursor",
    "nscanned" : 439288,
    "nscannedObjects" : 439288,
    "n" : 1,
    "millis" : 303,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {

    }
}
> db.ip.ensureIndex({ip1:1, ip2:1})
> db.ip.find({ip1:{$lte:1968177160}, ip2:{$gte:1968177160}}).explain()
{
    "cursor" : "BtreeCursor ip1_1_ip2_1",
    "nscanned" : 394583,
    "nscannedObjects" : 1,
    "n" : 1,
    "millis" : 1683,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
        "ip1" : [
            [
                -1.7976931348623157e+308,
                1968177160
            ]
        ],
        "ip2" : [
            [
                1968177160,
                1.7976931348623157e+308
            ]
        ]
    }
}
豫ICP备09035262号-1