我们在 mongodb 篇中介绍了如何使用 mongodb 进行地图的距离排序和筛选,今天我们来介绍一下,用 Java 和 SpringData 来实现的时候,需要注意的一些知识点。
首先,我们需要为实体设置地图索引。在 SpringData 中,我们可以通过使用 @GeoSpatialIndexed 注解来设置索引。但是这个索引注解默认使用的是2d索引,我们希望使用 2dsphere 索引,因此我们需要将重新设置这个注解的 type(type= GeoSpatialIndexType.GEO_2DSPHERE)。姿势如下:
@Document(collection = "location")
public class Location {
@Field(value = "lng")
private double lng;
@Field(value = "lat")
private double lat;
@Field(value = "location")
@GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)
private double[] location;
}
在设置好索引之后,我们就可以愉快的开始距离的排序了,第一种方式默认按照由近到远排序。姿势如下:
public List<Location> getNearLocation(double lng, double lat) {
Query query = new Query();
Point point = new Point(lng, lat);
Criteria locCri = Criteria.where("location").nearSphere(point);
query.addCriteria(locCri);
return mongoAccess.find(query, Location.class);
}
除了上面这种方式,按照离我最近,还可以使用 Aggregate 来实现。姿势如下:
public List<Location> getNearLocation(double lng, double lat) {
Point point = new Point(lng, lat);
Sort disSort = new Sort(Sort.Direction.ASC, "distance");
List<AggregationOperation> aggregationOperations = new ArrayList<>();
aggregationOperations.add(Aggregation.geoNear(NearQuery.near(point).inKilometers().spherical(true), "distance"));
aggregationOperations.add(Aggregation.sort(disSort));
Aggregation aggregation = Aggregation.newAggregation(aggregationOperations);
AggregationResults<Location> results = this.mongoAccess.aggregate(aggregation, Location.class, Location.class);
return results.getMappedResults();
}
如果我们希望查询以某个点为中心的圆几公里以内的位置数据,那你的姿势可以如下:
public List<Location> getCircleLocation(double lng, double lat, double radius) {
//获取半径内的所有位置
Point point = new Point(lng, lat);
Distance distance = new Distance(radius, Metrics.KILOMETERS);
Circle circle = new Circle(point, distance);
Criteria locCri = Criteria.where("location").withinSphere(circle);
Query query = new Query();
query.addCriteria(locCri);
return mongoAccess.find(query, Location.class);
}
注:代码中的 mongoAccess 为 mongodb 的基本操作封装,大家替换为自己的实现即可。