基于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中文社区,里面都有具体的介绍。

时间: 2024-11-10 15:43:09

基于mongodb的地理检索实现的相关文章

MongoShake——基于MongoDB的跨数据中心的数据复制平台

摘要: MongoShake是基于MongoDB的通用型平台服务,作为数据连通的桥梁,打通各个闭环节点的通道.通过MongoShake的订阅消费,可以灵活对接以适应不同场景,例如日志订阅.数据中心同步.监控审计等.其中,集群数据同步作为核心应用场景,能够灵活实现灾备和多活的业务场景. 背景 在当前的数据库系统生态中,大部分系统都支持多个节点实例间的数据同步机制,如Mysql Master/Slave主从同步,Redis AOF主从同步等,MongoDB更是支持3节点及以上的副本集同步,上述机制很

基于MongoDB分布式存储进行MapReduce并行查询

中介绍了如何基于Mongodb进行关系型数据的分布式存储,有了存储就会牵扯到查询.虽然用普通的方式也可以进行查询,但今天要介绍的是如何使用MONGODB中提供的MapReduce功能进行查询.      有关MongoDb的MapReduce之前我写过一篇文章 Mongodb Mapreduce 初窥, 今天介绍如何基于sharding机制进行mapreduce查询.在MongoDB的官方文档中,这么一句话: Sharded Environments      In sharded enviro

ip代理池-基于mongodb数据库

代码用的python2.7,抓取xici免费代理,检测放入数据库中,为以后爬虫做准备.下面直接上代码 1 #-*-encoding=utf-8-*- 2 3 import requests 4 from lxml import etree 5 import time 6 import pymongo 7 from multiprocessing import Pool 8 9 10 class Getproxy(object): 11 def __init__(self): 12 self.he

基于MongoDB.Driver的扩展

由于MongoDB.Driver中的Find方法也支持表达式写法,结合[通用查询设计思想]这篇文章中的查询思想,个人基于MongoDB扩展了一些常用的方法. 首先我们从常用的查询开始,由于MongoDB.Driver支持类似于AutoMapper返回的指定属性(Project<TDto>方法),所以这里都是基于泛型的扩展 /// <summary> /// 同步查询指定条件的数据,并且返回指定类型TDto /// </summary> /// <typeparam

基于 MongoDB 动态字段设计的探索 (二) 聚合操作

业务需求及设计见前文:基于 MongoDB 动态字段设计的探索 根据专业计算各科平均分 (总分.最高分.最低分) public Object avg(String major){ Aggregation aggregation = Aggregation.newAggregation( Aggregation.unwind("courseList"), Aggregation.match(Criteria.where("major").is(major)), Agg

基于mongoDB的capped collection的性能优化

MonitorLogging改造(消息接入) 改造前架构: 可以看出原来的流程中,大量业务分析,业务接入耦合在web服务层.大量操作,导致线程线性的挂起线程. 改造后: 将业务通讯抽象成为MonitorQueueManager,并将业务主题抽象放到各自的collection中. 形如: 抽象为一个结构topic,content针对业务分为若干个主题.方便以后切换到mq或者其他的队列中. MonitorSchedule改造(消息集中处理) 原有处理流程 当时业务比较少,只有一个主处理流程,所以强耦

朴灵:基于MongoDB与NodeJS构建物联网系统

目标 基于阿里云服务快速构建物联网系统 准备工作 ECS MongoDB EMR Alinode 中间件代码 注意事项:ECS,MongoDB 可以选择按量计费的服务. 实例申请 Step1 拿到阿里云账号,登陆 Step2 控制台新建实例 新建实例: https://mongodb.console.aliyun.com/#/buy/mongodb?chargeType=PostPaid 新建实例时,请选择『按量付费』类型,并需要选择合适的CPU 内存规格,磁盘空间.并设置 root 密码(后续

mongodb的地理空间索引常见的问题

创建地理空间索引注意事项 创建地理空间索引失败,提示错误信息如下 > db.places.ensureIndex({"loc":"2dsphere"}){"createdCollectionAutomatically" : false,"numIndexesBefore" : 1,"ok" : 0,"errmsg" : "Can't extract geo keys fr

基于 Google-S2 的地理相册服务实现及应用

马蜂窝技术原创内容,更多干货请关注公众号:mfwtech 随着智能手机存储容量的增大,以及相册备份技术的普及,我们可以随时随地用手机影像记录生活,在手机中存储几千张甚至上万张照片已经是很常见的事情.但另一方面,当我们想从这么多张照片中去找到一张,也是一件麻烦事. 马蜂窝作为旅行玩乐平台,希望实现「会玩的人」与「好玩的事」之间的连接.众多旅行爱好者在这里记录和分享他们的旅行记忆,使马蜂窝在旅游 UGC 领域累积了大量内容.因此,不断优化用户在发布内容时的体验是我们一直努力的主向. 用照片.视频记录