溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

基于mongodb的地理檢索實(shí)現(xiàn)

發(fā)布時(shí)間:2020-03-01 11:24:17 來源:網(wǎng)絡(luò) 閱讀:476 作者:微子Lee 欄目:MongoDB數(shù)據(jù)庫

使用mongoDB不是很多,記得以前做“家長助手”的時(shí)候,使用過一點(diǎn)。只是在去年做“派單系統(tǒng)”的時(shí)候,又再一次使用mongoDB。

在這里先簡單介紹一下派單系統(tǒng),派單系統(tǒng)在云足療(O2O,上門足療)里一個(gè)專門負(fù)責(zé)訂單派送,提高訂單完成效率的一個(gè)系統(tǒng)。主要是當(dāng)一個(gè)來了之后,會(huì)根據(jù)訂單的服務(wù)項(xiàng)目、服務(wù)時(shí)間和服務(wù)地點(diǎn),快速找到最合適最優(yōu)秀的技師,返回給用戶。由于上門足療特殊行業(yè)的要求,不能給訂單指定技師直接下單。而是將篩選的一些優(yōu)秀的技師返回給用戶,讓用戶自己去選擇指派給哪位技師。

項(xiàng)目背景說完了之后,就是技術(shù)方案選擇的問題。一開始,是想基于HBase一個(gè)分布式的、面向列的開源數(shù)據(jù)庫去存儲(chǔ)技師上報(bào)經(jīng)緯度。然后通過storm流式計(jì)算技師的位置。后來,感覺HBase過重而且還不便于維護(hù)。同時(shí),又考慮到小公司的都會(huì)面對的一個(gè)問題——成本問題。就放棄了這一種方案。然后,就想選擇一個(gè)非關(guān)系型數(shù)據(jù)庫去存住數(shù)據(jù),這時(shí)候就想到了Mongodb。好了,這是數(shù)據(jù)層。分布式架構(gòu)我們使用的阿里的dubbo。選擇它的原因就不多說了。首先是,市面上使用廣泛吧。以后,會(huì)具體講述其特點(diǎn)。分布式的管控使用的是zookeeper,跨系統(tǒng)中間件使用的是ActiveMq。這個(gè)還是要簡單說一下為什么要選擇這個(gè),而沒有選擇市面上用的比較多的RocketMq。最重要的一個(gè)原因時(shí)以前的工作中使用過,而對MQ的應(yīng)用場景是師傅端經(jīng)緯度上報(bào),消息的可靠性又不是很高,同時(shí)降低了學(xué)習(xí)成本。說到這里,感覺說的太多了,今天主要說的是mongodb的應(yīng)用。

接下來就寫一個(gè)基于mongodb的地理檢索的實(shí)現(xiàn)吧!

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);
    //隨機(jī)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();
        //數(shù)量
        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);
        //調(diào)用DAO層,獲取數(shù)據(jù)
        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 參數(shù)異常");
        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實(shí)現(xiàn)地理檢索的功能,關(guān)于mongodb地理檢索的方式有很多種,具體可以參考mongodb中文社區(qū),里面都有具體的介紹。


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI