lbs纯真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
]
]
}
}