结合MongoDB开发LBS应用——附近的人
"The palest ink is better than the best memory"——好记性不如烂笔头。2013~2015补记
题记:
2014.7月业务数据增长,附近人脉功能模块导致Mysql数据库成为服务器瓶颈
关键词:
附近的人、LBS、Geo、geoNear、maxDistance、distanceMultiplier、2dsphere
方案:
1.基于Mysql数据库,ABS函数(当前出现问题)
2.基于Mysql采用GeoHash索引(生产环境5.1版本不支持,全库升级比较麻烦)
3.基于Solr的geodist和geohash(上家公司做附近商铺实现过,目前还没引入Solr)
4.基于Mongo的geo(当前正在使用Mongo,值得尝试一下,和Solr比较比较)
MongoDB原生支持地理位置索引,可以直接用于位置距离计算和查询。查询结果默认将会由近到远排序,而且查询结果也包含目标点对象、距离目标点的距离等信息
代码:
1.mongo库中数据格式:
{"_id": ObjectId("582c13293e5467eefbd94ad9"),"uid": NumberInt(2448286),"gps": {"lon": 121.470238,"lat": 31.272408},"flag": NumberInt(1),"createTime": NumberLong(1479440591566)
}
2.需要添加geo索引(https://docs.mongodb.com/manual/core/geospatial-indexes/):
db.mydb.createIndex( { "gps": "2d" } )
3.核心java实现代码(建议先熟悉官方文档,写好shell):
/*** 保存或更新GPS* @param uid* @param longitude* @param latitude* @param flag* @param createTime* @return* @throws Exception*/
@Override
public int saveOrUpdateGPS(int uid, double longitude, double latitude,int flag,long createTime) throws Exception {if(longitude < -180 || longitude > 180 || latitude < -90 || latitude > 90){return -1;}DBObject where = new BasicDBObject("uid", uid);DBCollection dbc = this.getUserGPSCollection();DBObject gps = new BasicDBObject();gps.put("lon", longitude);gps.put("lat", latitude);DBObject doc = new BasicDBObject();doc.put("uid", uid);doc.put("gps", gps);doc.put("flag", flag);doc.put("createTime", createTime);DBObject newDoc = new BasicDBObject();newDoc.put("$set", doc);return dbc.update(where, newDoc, true, true).getN();}
/*** 获取附近用户* <p>* * <Strong>MongoDB实现参考官方资料:</Strong>* <br>* 1.<link>http://docs.mongodb.org/manual/core/aggregation-introduction/</link>* 2.<link>http://docs.mongodb.org/manual/reference/operator/aggregation/geoNear/</link>* * <p>* @param uid* @param startTime* @param longitude* @param latitude* @param maxDistance(单位KM)* @param maxNum* @param page* @param pageSize* @return* @throws Exception*/
@Override
public List<JSONObject> getNearUIDS(int uid,long startTime, double longitude,double latitude, double maxDistance,int maxNum ,int page,int pageSize) throws Exception {DBObject near = new BasicDBObject("lon", longitude).append("lat", latitude);DBObject where = new BasicDBObject();where.put("flag", 1);where.put("uid", new BasicDBObject(QueryOperators.NE,uid));where.put("createTime", new BasicDBObject(QueryOperators.GTE, startTime));DBObject geoFields = new BasicDBObject();geoFields.put("geoNear", "user_gps");geoFields.put("near", near);geoFields.put("spherical", "true");geoFields.put("maxDistance", maxDistance/6371);geoFields.put("query", where);geoFields.put("distanceMultiplier", 6371);//注意geoFields.put("distanceField", "dis");geoFields.put("num", maxNum);DBObject geo = new BasicDBObject("$geoNear",geoFields);DBObject projectFields = new BasicDBObject();projectFields.put("_id", 0);projectFields.put("uid", 1);projectFields.put("dis", 1);projectFields.put("createTime", 1);DBObject project = new BasicDBObject("$project", projectFields );// DBObject orderBy = new BasicDBObject("dis",1);
// orderBy.put("createTime", -1);
// DBObject sort = new BasicDBObject("$sort",orderBy);//整体sort可以去掉DBObject skip = new BasicDBObject("$skip",(page - 1) * pageSize);DBObject limit = new BasicDBObject("$limit",pageSize);DBCollection dbc = this.getUserGPSCollection();// AggregationOutput out = dbc.aggregate(geo,project,sort,skip,limit);AggregationOutput out = dbc.aggregate(geo,project,skip,limit);Iterable<DBObject> res = out.results();Iterator<DBObject> iterator = res.iterator();List<JSONObject> resList = new LinkedList<JSONObject>();while(iterator.hasNext()){DBObject one = iterator.next();JSONObject json = JSONObject.fromObject(one.toString());resList.add(json);}return resList;}
实际产品:
(不显示实际具体距离,是有意而为之)
参考:
1.http://docs.mongodb.org/manual/core/aggregation-introduction/
2.http://docs.mongodb.org/manual/reference/operator/aggregation/geoNear/
3.http://www.infoq.com/cn/articles/depth-study-of-Symfony2
4.https://wiki.apache.org/solr/SpatialSearch/
结合MongoDB开发LBS应用——附近的人相关推荐
- 结合MongoDB开发LBS应用(转)
原文链接:结合MongoDB开发LBS应用 简介 随着近几年各类移动终端的迅速普及,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理.我所在 ...
- MongoDB开发LBS应用
随着近几年各类移动终端的迅速普及,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理. 关于LBS的详细介绍及通用的几个解决方案,可以参考:深 ...
- 12.Laravel5学习笔记:使用mongodb开发LBS应用
做LBS应用有多种方案,这里介绍一下在Laravel5中使用Mongodb来实现,文章参考了: 深入浅出Symfony2 - 结合MongoDB开发LBS应用 环境说明: php集成环境:xampp ...
- 结合MongoDB开发LBS应用
http://www.cnblogs.com/jifeng/p/4356052.html 然后列举一下需求: 1.实时性要高,有频繁的更新和读取 2.可按距离排序支持分页 3.支持多条件筛选(一个经纬 ...
- 结合MongoDB开发LBS应用(mongodb geo)
简介 随着近几年各类移动终端的迅速普及,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理.我所在的项目也正从事相关系统的开发,我们使用的是S ...
- 利用mongodb开发lbs应用实践【转】
近期作为突击队员,与同事一起突击构建了一个简单的lbs系统.当前比较主流的做法是使用mongodb,因为其已经封装了常用的lbs基本操作(如查找附近的人),功能非常强大,对于开发周期只有一周的项目,m ...
- 利用mongodb开发lbs应用实践
转载:http://www.tuicool.com/articles/feueEnz 近期作为突击队员,与同事一起突击构建了一个简单的lbs系统.当前比较主流的做法是使用mongodb,因为其已经封装 ...
- MongoDB开发使用手册
一.基础部分 MongDB简介 NOSQL历史和产生原因 原因: 互联网用户数的增长和用户参与互联网习惯的改变 初始的静态内容网站,提供中心化的内容服务, 特点: 中心化,用户阅读内容 系统:Apac ...
- mongodb 输出数组字段_三分钟 mongodb 开发快速上手
三分钟 mongodb 开发快速上手 小熊昨天晚上做了一个非常真实的噩梦,有读者朋友催我"怎么又没有发文!让我们等的好辛苦",今天一睁开眼眼看后台留言,特么,居然是真的! 我bil ...
最新文章
- android混淆和反编译
- iOS限定UITextField的输入格式
- 传孙正义领投滴滴无人车3亿美元新融资,此前软银宣布出售阿里股份等资产
- HDU Redraw Beautiful Drawings 推断最大流是否唯一解
- excel中VBa应用总结
- 不高兴的津津(洛谷-P1085)
- 恢复 linux系统密码
- 基于vue2.0 + elementUI 后台管理平台
- 程序员踩坑之旅:将 75000 行 iOS 原生代码迁移到 Flutter!
- Netflix的Hystrix使用教程
- python-回文字符串
- 关于min max 函数凹凸性,以及报童模型中期望库存,期望缺货量的性质
- Rust 调用标准C接口的自定义c/c++库,FFI详解
- 链表 java 实现
- 读书笔记-数据库系统概念-chapter3SQL
- 微信开放标签wx-open-launch-app
- Oracle基础学习
- 还在烦恼Word怎么转PPT?教你一种方法告别复制粘贴
- Sitewhere物联网云平台安装
- 【leetcode】脑子打结的题
热门文章
- 作为一名Python程序员,论听歌的正确姿势?
- centos的cd与pwd指令
- 写给即将踏上工作岗位的人
- 软件开发行业如何在激烈竞争中取胜
- es6中reduce的用法_25个你不得不知道的数组reduce高级用法
- Web前端-Vue ElementUI点击Table 索引行获取index处理
- 华为云MVP高浩:打破AI开发瓶颈,解决数据、算法、算力三大难题
- AttributeError: module ‘xxx‘ has no attribute
- android studio手动导入module
- 对FTP服务器文件夹分析,ftp服务器的主目录根文件夹