首页 > 代码库 > 基于mongodb的地理检索实现
基于mongodb的地理检索实现
使用mongoDB不是很多,记得以前做“家长助手”的时候,使用过一点。只是在去年做“派单系统”的时候,又再一次使用mongoDB。
在这里先简单介绍一下派单系统,派单系统在云足疗(O2O,上门足疗)里一个专门负责订单派送,提高订单完成效率的一个系统。主要是当一个来了之后,会根据订单的服务项目、服务时间和服务地点,快速找到最合适最优秀的技师,返回给用户。由于上门足疗特殊行业的要求,不能给订单指定技师直接下单。而是将筛选的一些优秀的技师返回给用户,让用户自己去选择指派给哪位技师。
项目背景说完了之后,就是技术方案选择的问题。一开始,是想基于HBase一个分布式的、面向列的开源数据库去存储技师上报经纬度。然后通过storm流式计算技师的位置。后来,感觉HBase过重而且还不便于维护。同时,又考虑到小公司的都会面对的一个问题——成本问题。就放弃了这一种方案。然后,就想选择一个非关系型数据库去存住数据,这时候就想到了Mongodb。好了,这是数据层。分布式架构我们使用的阿里的dubbo。选择它的原因就不多说了。首先是,市面上使用广泛吧。以后,会具体讲述其特点。分布式的管控使用的是zookeeper,跨系统中间件使用的是ActiveMq。这个还是要简单说一下为什么要选择这个,而没有选择市面上用的比较多的RocketMq。最重要的一个原因时以前的工作中使用过,而对MQ的应用场景是师傅端经纬度上报,消息的可靠性又不是很高,同时降低了学习成本。说到这里,感觉说的太多了,今天主要说的是mongodb的应用。
接下来就写一个基于mongodb的地理检索的实现吧!
Controller层
//查询附近 @ResponseBody @RequestMapping(value = "/geoNearN", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"}) public String testQueryMongoTopN() { CarPointNearQuery personQuery = new CarPointNearQuery(); Random random = new Random(); double[] arr = MongoUtil.getRandomLocation(); //最多查100条记录 personQuery.setCount(100); //随机1km米到10km int distance = random.nextInt(10); personQuery.setDistance(distance); personQuery.setLongitude(arr[0]); personQuery.setLatitude(arr[1]); return JSON.toJSONString(mongoLbsService.geoNearCarPoint(personQuery)); }
Service层
public CarPointNearResult geoNearCarPoint(CarPointNearQuery carPointNearQuery) { CarPointNearResult carPointNearResult = new CarPointNearResult(); if(carPointNearQuery != null && carPointNearQuery.getLongitude() != 0.0D && carPointNearQuery.getLatitude() != 0.0D) { Point point = new Point(carPointNearQuery.getLongitude(), carPointNearQuery.getLatitude()); NearQuery near = NearQuery.near(point, Metrics.KILOMETERS); Query query = new Query(); //数量 query.limit(carPointNearQuery.getCount() == 0?100:carPointNearQuery.getCount()); near.query(query); //距离 near.maxDistance(new Distance(carPointNearQuery.getDistance() == 0.0D?1.0D:carPointNearQuery.getDistance(), Metrics.KILOMETERS)); near.spherical(true); //调用DAO层,获取数据 GeoResults geoResults = this.carPointDao.geoNear(near, CarPoint.class, "carPoint"); carPointNearQuery.setCount(geoResults.getContent().size()); carPointNearQuery.setDistance(near.getMaxDistance().getValue()); carPointNearResult.setCarPointNearQuery(carPointNearQuery); List geoResultsContent = geoResults.getContent(); ArrayList resultsList = new ArrayList(); Iterator i$ = geoResultsContent.iterator(); while(i$.hasNext()) { GeoResult geoResult = (GeoResult)i$.next(); CarPointResult carPointResult = new CarPointResult(); carPointResult.setDistance(geoResult.getDistance().getValue()); carPointResult.setCarPoint((CarPoint)geoResult.getContent()); resultsList.add(carPointResult); } carPointNearResult.setCarPointList(resultsList); return carPointNearResult; } else { logger.error("geoNear 参数异常"); carPointNearResult.setErrorCode(ErrorCode.PARAM_ERROR); return null; } }
DAO层
public GeoResults<T> geoNear(NearQuery near, Class<T> clazz, String collectionName) { //直接使用mongoTemplate就可以了 GeoResults geoResults = this.mongoTemplate.geoNear(near, clazz, collectionName); return geoResults; }
以上就是使用mongodbTemplate实现地理检索的功能,关于mongodb地理检索的方式有很多种,具体可以参考mongodb中文社区,里面都有具体的介绍。
基于mongodb的地理检索实现