1、项目关联jar文件
2、配置mongodb.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- Default bean name is 'mongo' -->
<mongo:mongo host="192.168.1.88" port="27017" />
<mongo:db-factory dbname="database" mongo-ref="mongo" />
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
<bean id="businessDao" class="com.spring.operation.BusinessDao"></bean>
<bean id="businessPositionDao" class="com.spring.operation.BusinessPositionDao"></bean>
<bean id="mongoDaoImpl" class="com.spring.operation.MongoDaoImpl"></bean>
</beans>
3、mongodb 父接口类
<span style="font-size:12px;">package com.spring.mongodb;
import java.util.List;
import com.mongodb.DBObject;
/**
* mongodb 父接口类
* @author zhouzhigang
* @version 1.1
* @date 2016年11月09日-下午1:42: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);
} </span>
<span style="font-size:12px;">package com.spring.mongodb;
import com.mongodb.DBObject;
import com.spring.entity.Point;
import java.util.List;
/**
* Mondodb 地址运算 接口类
*
* @author zhouzhigang
* @version 1.1
* @date 2016年11月09日-下午1:50: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);
}</span><span style="font-size: 15px;">
</span>
5、mongodb 服务实现类
package com.spring.operation;
import com.mongodb.AggregationOptions;
import com.mongodb.BasicDBObject;
import com.mongodb.Cursor;
import com.mongodb.DBObject;
import com.spring.entity.Point;
import com.spring.mongodb.MongoGeoDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class MongoDaoImpl implements MongoGeoDao {
private static Logger logger = LoggerFactory.getLogger(MongoDaoImpl.class);
@Autowired
private MongoTemplate mongoTemplate;
public DBObject findOne(String collection, DBObject query, DBObject fields) {
return mongoTemplate.getCollection(collection).findOne(query, fields);
}
public List<DBObject> find(String collection, DBObject query, DBObject fields, DBObject orderBy, int pageNum, int pageSize) {
List<DBObject> list = new ArrayList<DBObject>();
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;
}
public List<DBObject> find(String collection, DBObject query, DBObject fields, DBObject orderBy, int limit) {
List<DBObject> list = new ArrayList<DBObject>();
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;
}
public void delete(String collection, DBObject dbObject) {
mongoTemplate.getCollection(collection).remove(dbObject);
}
public void save(String collection, DBObject dbObject) {
mongoTemplate.getCollection(collection).save(dbObject);
}
public void update(String collection, DBObject query, DBObject update, boolean upsert, boolean multi) {
mongoTemplate.getCollection(collection).update(query, update, upsert, multi);
}
public Long count(String collection, DBObject query) {
return mongoTemplate.getCollection(collection).count(query);
}
public List<?> distinct(String collection, String key, DBObject query) {
return mongoTemplate.getCollection(collection).distinct(key, query);
}
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<DBObject>();
BasicDBObject aggregate = new BasicDBObject("$geoNear",
new BasicDBObject("near",new BasicDBObject("type","Point").append("coordinates",new double[]{point.getLng(), point.getLat()}))
.append("distanceField","dist.calculated")
.append("query", query)
.append("num", limit)
.append("maxDistance", maxDistance)
.append("spherical",true)
);
pipeLine.add(aggregate);
Cursor cursor=mongoTemplate.getCollection(collection).aggregate(pipeLine, AggregationOptions.builder().build());
List<DBObject> list = new LinkedList<DBObject>();
while (cursor.hasNext()) {
list.add(cursor.next());
}
return list;
}
public List<DBObject> withinCircle(String collection,String locationField, Point center,
long radius, DBObject fields, DBObject query, int limit) {
LinkedList<Object> circle = new LinkedList<Object>();
//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();
}
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();
}
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<List<double[]>>();
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();
}
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<List<List<double[]>>>();
for (List<double[]> polygon : polygons) {
List<List<double[]>> temp = new LinkedList<List<double[]>>();
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();
}
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<double[]>();
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]}})
db.集合名称.ensureIndex( { loc : "2dsphere" } )
8、调用实例
package com.spring.main;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.spring.entity.BusinessPosition;
import com.spring.entity.Point;
import com.spring.entity.Positions;
import com.spring.operation.BusinessPositionDao;
import com.spring.operation.MongoDaoImpl;
@RunWith(SpringJUnit4ClassRunner.class) //使用junit4进行测试
@ContextConfiguration(locations={"classpath*:mongodb.xml"})
public class DistanceMain {
@Autowired
private BusinessPositionDao businessPositionDao;
@Autowired
private MongoDaoImpl mongoDaoImpl;
@Test
public void test1(){
DBObject object = new BasicDBObject();
object.put("address", "南京 安德门");
DBObject subObject = new BasicDBObject();
subObject.put("type", "Point");
double[] addre = new double[2];
addre[0] = 118.768964;
addre[1] = 31.99646;
subObject.put("coordinates",addre);
object.put("loc", subObject);
mongoDaoImpl.save("positions",object);
System.out.println("数据插入成功");
}
@Test
public void test2(){
double lng = 118.768964;
double lat = 31.99656;
Point point = new Point();
point.setLat(lat);
point.setLng(lng);
DBObject query = new BasicDBObject();
int limit =10;
long maxDistance = 1000;
List<DBObject> list = mongoDaoImpl.geoNear("positions", query, point, limit, maxDistance);
if(list !=null && list.size()>0){
for(DBObject obj:list){
System.out.println("商家地址:"+(String)obj.get("address"));
}
}
}
}<span style="font-size: 15px;">
</span>