说重点:
以前也搞过类似的功能点,根据用户当前的GPS坐标搜索附近的银行,用户的位置是可以随便乱跑的,并且这种功能一般他搜了一次找到了就不会再找第二次了,所以用memcache这种缓存方案思路是不对的。当时几百万数据运转在Mysql上,每次调用这个功能俺都心惊胆颤的,当然,我们也搞了几次优化
1:银行的GPS位置信息首先做预处理,把x,y的平方什么的先当冗余字段存起来
2:先圈一个大范围,把数据量降下来,再按距离算
3:用户想要的信息也许不止一页,先弄五页出来,存在memcache,先保证下次来拿的时候节省数据库一点资源
总的来说,这方案搞起来比较纠结…..
好吧,新项目总得来点新气象。
先后研究了Cassandra,HBase,mongoDB三种NoSql类的数据库,mongoDB的地理空间索引功能的确比较符合我们的胃口。
好,下面,上代码
1: 数据结构
gps键的值是包含两个键的内嵌文档
2:建2d索引(没有索引运行不起哦)
public static void createGroup2DIndex(){
try {
Mongo m = new Mongo(DB_Address, 27017);
DB db = m.getDB(DB_Name);
DBCollection collection = db.getCollection(Position);
collection.createIndex(new BasicDBObject("gps", "2d"));
} catch (Exception e) {
//TODO
}
}
3:查询
public static void getPositionBox(){
try {
Mongo mongo = new Mongo(DB_Address, 27017);
DB db = mongo.getDB(DB_Name);
DBCollection collection = db.getCollection("Position");
BasicDBObject searchQuery = new BasicDBObject();
BasicDBObject centerQuery = new BasicDBObject("$center",new Box(new Gps(Double.valueOf(104), Double.valueOf(30)), 2.4d));
BasicDBObject withinQuery = new BasicDBObject("$within", centerQuery);
searchQuery.put("gps", withinQuery);
DBCursor cursor = collection.find(searchQuery);
….处理返回结果
} catch (Exception e) {
//TODO
}
}
Ok!选择了好友,我们就可以一起出发了!自驾游对讲机帮我们记录一路上的欢声笑语,枯燥旅程上的点点滴滴,既能方便的打情骂俏,又能准确的位置跟踪, 我们是快乐的自驾族,谁也跑不了。