您的位置:首页 > 数据库 > Mongodb

基于mongodb的地理检索实现

2016-12-22 00:00 155 查看
使用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((CarPoi
3ff0
nt)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中文社区,里面都有具体的介绍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: