(内心背景:想顺便学习mongodb)
经查阅mongodb相关文档,发现Mongodb中的$nearSphere很适合这个场景,于是经技术评审后决定采用$nearSphere来做。
$nearSphere
$nearSphere需要地理空间索引:
2 dsphere定义为 GeoJSON 点的位置数据索引
2 d定义为 legacy 坐标对的位置数据的索引。要在GeoJSON 指出上使用2 d索引,请在 GeoJSON object 的coordinates
字段上创建索引。
$nearSphere operator 可以指定以 GeoJSON point 或 legacy 坐标点。
要指定GeoJSON Point,请使用以下语法:
{
$nearSphere: {
$geometry: {
type : "Point",
coordinates : [ , ]
},
$minDistance: ,
$maxDistance:
}
}
考虑一个包含location
字段且具有2 dsphere索引的文档的集合places
。
然后,以下 example 返回其location
距指定点至少1000
米并且距离指定点最多5000
米,从最近到最远排序:
db.places.find(
{
location: {
$nearSphere: {
$geometry: {
type : "Point",
coordinates : [ -73.9667, 40.78 ]
},
$minDistance: 1000,
$maxDistance: 5000
}
}
}
)
/**
* 指定一个点,返回该点附近的坐标点且是由近到远,$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 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.getX(), center.getY()}))
.append("$minDistance", minDistance)
.append("$maxDistance", maxDistance)));
return mongoTemplate.getCollection(collection).find(query, fields).limit(limit).toArray();
}
1、locationField指定字段必须是已经建立了索引的
如上面所示,添加2dsphere索引后的列才可以使用nearSphere查询。
2、nearSphere查询出来的结果是根据附近的坐标点由近到远排序的,这样就很方便了,不需要二次排序,我之前就是因为不知道这个特性浪费了一点时间去搞这个排序。