spring java mongodb geo 位置搜尋服務 樣本

來源:互聯網
上載者:User

標籤:

1、配置 pom.xml,在原有的spring項目中添加以下2個即可。

<span style="white-space:pre"></span><!-- mongo db 驅動--><dependency>    <groupId>org.mongodb</groupId>    <artifactId>mongo-java-driver</artifactId>    <version>3.2.2</version></dependency><!-- spring-data-mongodb --><dependency>    <groupId>org.springframework.data</groupId>    <artifactId>spring-data-mongodb</artifactId>    <version>1.9.2.RELEASE</version></dependency>

2、配置 spring-data-mongo.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:mongo="http://www.springframework.org/schema/data/mongo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/data/mongo    http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"><!-- Default bean name is 'mongo' --><mongo:mongo host="localhost" port="27017"/><!-- Offers convenience methods and automatic mapping between MongoDB JSON documents and your domain classes. -->  <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">  <constructor-arg ref="mongo"/>    <constructor-arg name="databaseName" value="test"/>  </bean></beans>

3、mongodb 父介面類


package com.zjp.cache;import java.util.List;import com.mongodb.DBObject;/** * mongodb 父介面類 * @author babylon * @version 1.1 * @date 2016年7月12日-下午1:22:23 */public interface  MongoDao {    public DBObject findOne(String collection, DBObject query, DBObject fields);     public List<DBObject> find(String collection, DBObject query, DBObject fields, DBObject orderBy, int pageNum, int pageSize);     public List<DBObject> find(String collection, DBObject query, DBObject fields, DBObject orderBy, int limit);     public void delete(String collection, DBObject dbObject);     public void save(String collection, DBObject dbObject);     public void update(String collection, DBObject query, DBObject update, boolean upsert, boolean multi);     public Long count(String collection, DBObject query);     public List<?> distinct(String collection, String key, DBObject query); }

4、Mondodb 地址運算 介面類


package com.zjp.cache; import com.mongodb.DBObject; import java.util.List; /** * Mondodb 地址運算 介面類 * * @author babylon * @version 1.1 * @date 2016年7月12日-下午1:42:06 */public interface MongoGeoDao extends MongoDao{
   /**     * 彙總查詢,查詢一個點附近的點,並返回每一個點到該中心點的距離,在座標表分區的情況下$nearSphere不支援,     * 可以使用該方法進行查詢     * @param collection    集合名稱     * @param query         查詢條件     * @param point         中心點座標     * @param limit         返回記錄數量限制     * @param maxDistance   最大距離     * @return              非NULL的list     */    public List<DBObject> geoNear(String collection, DBObject query, Point point,int limit, long maxDistance) ;    /**     * 查詢在圓形地區內的座標點,需要指定中心點座標和半徑,半徑單位是米     *     * @param collection    集合名稱     * @param locationField 座標欄位     * @param center        中心點座標[經度,緯度]     * @param radius        半徑 單位:米     * @param fields        查詢欄位     * @param query         查詢條件     * @param limit         返回記錄限制數量     * @return              非NULL的list     */    public List<DBObject> withinCircle(String collection,String locationField, Point center, long radius,                                       DBObject fields, DBObject query, int limit);     /**     * 指定一個點,返回該點附近的座標點且是由近到遠,$nearSphere 需要建立索引2dsphere 或者2d,並且支援GeoJSON和一般座標組     * 注意: $nearSphere在分區的叢集中無效,使用geoNear     *     * @param collection    集合名稱     * @param locationField 座標欄位     * @param center        中心點座標[經度,緯度]     * @param minDistance   最近距離     * @param maxDistance   最遠距離     * @param query         查詢條件     * @param fields        查詢欄位     * @param limit         返回記錄限制數量     * @return              非NULL的list     */    public List<DBObject> nearSphere(String collection, String locationField, Point center, long minDistance, long maxDistance, DBObject query, DBObject fields, int limit);      /**     * 查詢位於指定一個封閉多邊形內的所有座標點,給定的多邊形座標點必須首位相接形成封閉的多邊形     * 如三角形     *       final LinkedList<double[]> polygon = new LinkedList<>();     *       polygon.addLast(new double[] {  121.36, 31.18 });     *       polygon.addLast(new double[] {  121.35, 31.36 });     *       polygon.addLast(new double[] {  121.39, 31.17 });     *       polygon.addLast(new double[] {  121.36, 31.18 });     *     * MongoDB將多邊形的邊界也作為查詢形狀的一部分     * @param collection    集合名稱     * @param locationField 座標欄位     * @param polygon       多邊形座標     * @param fields        查詢欄位     * @param query         查詢條件     * @param limit         返回記錄限制數量     * @return              非NULL的list     */    public List<DBObject> withinPolygon(String collection,String locationField,                                        List<double[]> polygon,DBObject fields,DBObject query,int limit);      /**     * 查詢位於指定多個封閉多邊形內的所有座標點,給定的多邊形座標點必須首位相接形成封閉的多邊形     * @param collection    集合名稱     * @param locationField 座標欄位     * @param polygons      多邊形座標 數組     * @param fields        查詢欄位     * @param query         查詢條件     * @param limit         返回記錄限制數量     * @return              非NULL的list     */    public List<DBObject> withinMultiPolygon(String collection,String locationField,                                        List<List<double[]>> polygons,DBObject fields,DBObject query,int limit);      /**     * 在矩形地區內尋找座標點,該方法僅僅在2d索引是支援,在2dsphere中不支援     * @param collection    集合名稱     * @param locationField 座標欄位     * @param bottomLeft    左下角     * @param upperRight    右上方     * @param fields        查詢欄位     * @param query         查詢條件     * @param limit         返回記錄限制數量     * @return              非NULL的list     */    @Deprecated    public List<DBObject> withinBox(String collection, String locationField,                                    Point bottomLeft, Point upperRight, DBObject fields, DBObject query,int limit); }

5、mongodb 服務實作類別


package com.zjp.service.impl; import com.mongodb.AggregationOptions;import com.mongodb.BasicDBObject;import com.mongodb.Cursor;import com.mongodb.DBObject;import com.zjp.cache.MongoGeoDao;import com.zjp.cache.Point;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.mongodb.core.MongoTemplate;import org.springframework.stereotype.Repository;import java.util.ArrayList;import java.util.LinkedList;import java.util.List; /** * mongodb 服務實作類別 * * @author babylon * @version 1.1 * @date 2016年7月12日-下午1:36:50 */@Repositorypublic class MongoDaoImpl implements MongoGeoDao {    private static Logger logger = LoggerFactory.getLogger(MongoDaoImpl.class);        @Autowired    private MongoTemplate mongoTemplate;     @Override    public DBObject findOne(String collection, DBObject query, DBObject fields) {        return mongoTemplate.getCollection(collection).findOne(query, fields);    }     @Override    public List<DBObject> find(String collection, DBObject query, DBObject fields, DBObject orderBy, int pageNum, int pageSize) {        List<DBObject> list = new ArrayList<>();        Cursor cursor = mongoTemplate.getCollection(collection).find(query, fields).skip((pageNum - 1) * pageSize).limit(pageSize).sort(orderBy);        while (cursor.hasNext()) {            list.add(cursor.next());        }        return list.size() > 0 ? list : null;    }     @Override    public List<DBObject> find(String collection, DBObject query, DBObject fields, DBObject orderBy, int limit) {        List<DBObject> list = new ArrayList<>();        Cursor cursor = mongoTemplate.getCollection(collection).find(query, fields).sort(orderBy).limit(limit);        while (cursor.hasNext()) {            list.add(cursor.next());        }        return list.size() > 0 ? list : null;    }     @Override    public void delete(String collection, DBObject dbObject) {        mongoTemplate.getCollection(collection).remove(dbObject);    }     @Override    public void save(String collection, DBObject dbObject) {        mongoTemplate.getCollection(collection).save(dbObject);    }     @Override    public void update(String collection, DBObject query, DBObject update, boolean upsert, boolean multi) {        mongoTemplate.getCollection(collection).update(query, update, upsert, multi);    }     @Override    public Long count(String collection, DBObject query) {        return mongoTemplate.getCollection(collection).count(query);    } @Override    public List<?> distinct(String collection, String key, DBObject query) {        return mongoTemplate.getCollection(collection).distinct(key, query);    }     @Override    public List<DBObject> geoNear(String collection, DBObject query, Point point, int limit, long maxDistance) {        if(query==null)            query = new BasicDBObject();         List<DBObject> pipeLine = new ArrayList<>();        BasicDBObject aggregate = new BasicDBObject("$geoNear",    new BasicDBObject("near",new BasicDBObject("type","Point").append("coordinates",new double[]{118.783799, 31.979234}))        .append("distanceField","dist.calculated")        .append("query", new BasicDBObject())        .append("num", 5)        .append("maxDistance", 5000)        .append("spherical",true)    );        pipeLine.add(aggregate);        Cursor cursor=mongoTemplate.getCollection(collection).aggregate(pipeLine, AggregationOptions.builder().build());        List<DBObject> list = new LinkedList<>();        while (cursor.hasNext()) {            list.add(cursor.next());        }        return list;    }     @Override    public List<DBObject> withinCircle(String collection,String locationField, Point center,                                       long radius, DBObject fields, DBObject query, int limit) {        LinkedList<Object> circle = new LinkedList<>();        //Set the center coordinate        circle.addLast(new double[]{center.getLng(),center.getLat()});        //Set the radius. unit:meter        circle.addLast(radius/6378137.0);         if(query==null)            query = new BasicDBObject();        query.put(locationField, new BasicDBObject("$geoWithin", new BasicDBObject("$centerSphere", circle)));        logger.info("withinCircle:{}",query.toString());        return mongoTemplate.getCollection(collection).find(query, fields).limit(limit).toArray();    }     @Override    public List<DBObject> nearSphere(String collection, String locationField, Point center,                                     long minDistance, long maxDistance, DBObject query, DBObject fields, int limit) {        if(query==null)            query = new BasicDBObject();         query.put(locationField,                new BasicDBObject("$nearSphere",                    new BasicDBObject("$geometry",                            new BasicDBObject("type","Point")                                    .append("coordinates",new double[]{center.getLng(),center.getLat()}))                            .append("$minDistance",minDistance)                            .append("$maxDistance",maxDistance)        ));        logger.info("nearSphere:{}",query.toString());        return mongoTemplate.getCollection(collection).find(query, fields).limit(limit).toArray();    }     @Override    public List<DBObject> withinPolygon(String collection, String locationField,                                        List<double[]> polygon, DBObject fields, DBObject query, int limit) {        if(query==null)            query = new BasicDBObject();         List<List<double[]>> polygons = new LinkedList<>();        polygons.add(polygon);        query.put(locationField, new BasicDBObject("$geoWithin",                new BasicDBObject("$geometry",                        new BasicDBObject("type","Polygon")                        .append("coordinates",polygons))));        logger.info("withinPolygon:{}",query.toString());        return mongoTemplate.getCollection(collection).find(query, fields).limit(limit).toArray();    }     @Override    public List<DBObject> withinMultiPolygon(String collection, String locationField, List<List<double[]>> polygons, DBObject fields, DBObject query, int limit) {        if(query==null)            query = new BasicDBObject();         List<List<List<double[]>>> list = new LinkedList<>();        for (List<double[]> polygon : polygons) {            List<List<double[]>> temp = new LinkedList<>();            temp.add(polygon);            list.add(temp);        }        query.put(locationField, new BasicDBObject("$geoWithin",                new BasicDBObject("$geometry",                        new BasicDBObject("type","MultiPolygon")                                .append("coordinates",list))));        logger.info("withinMultiPolygon:{}",query.toString());        return mongoTemplate.getCollection(collection).find(query, fields).limit(limit).toArray();    }     @Override    public List<DBObject> withinBox(String collection, String locationField, Point bottomLeft, Point upperRight, DBObject fields, DBObject query, int limit) {        if(query==null)            query = new BasicDBObject();         LinkedList<double[]> box = new LinkedList<>();        box.add(new double[]{bottomLeft.getLng(), bottomLeft.getLat()});        box.add(new double[]{upperRight.getLng(), upperRight.getLat()});         query.put(locationField, new BasicDBObject("$geoWithin", new BasicDBObject("$box", box)));        logger.info("withinBox:{}",query.toString());        return mongoTemplate.getCollection(collection).find(query, fields).limit(limit).toArray();    } }


6、添加資料


db.point.test.insert({"address" : "南京 祿口國際機場","loc" : { "type": "Point", "coordinates": [118.783799,31.979234]}})  db.point.test.insert({"address" : "南京 浦口公園","loc" : { "type": "Point", "coordinates": [118.639523,32.070078]}})  db.point.test.insert({"address" : "南京 火車站","loc" : { "type": "Point", "coordinates": [118.803032,32.09248]}})  db.point.test.insert({"address" : "南京 新街口","loc" : { "type": "Point", "coordinates": [118.790611,32.047616]}})  db.point.test.insert({"address" : "南京 張府園","loc" : { "type": "Point", "coordinates": [118.790427,32.03722]}})  db.point.test.insert({"address" : "南京 三山街","loc" : { "type": "Point", "coordinates": [118.788135,32.029064]}})  db.point.test.insert({"address" : "南京 中華門","loc" : { "type": "Point", "coordinates": [118.781161,32.013023]}})  db.point.test.insert({"address" : "南京 安德門","loc" : { "type": "Point", "coordinates": [118.768964,31.99646]}})


7、必須加索引 (為什麼:https://docs.mongodb.com/manual/reference/operator/aggregation/geoNear/)

db.point.test.ensureIndex( { loc : "2dsphere" } )  

8、調用執行個體

@Autowiredprivate MongoDaoImpl mongoDao;
DBObject query = new BasicDBObject();Point point = new Point();point.setLng(118.783799);point.setLat(31.979234);int limit = 5;Long maxDistance = 5000L; // 米List<DBObject> list = mongoDao.geoNear("point.test", query, point, limit, maxDistance);for(DBObject obj : list)   System.out.println(obj);


spring java mongodb geo 位置搜尋服務 樣本

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.