MongoDB中根据区域进行查询

时间:2025-01-21 11:37:00

 MongoDB 中根据经纬度(lon,lat)字段进行区域查询的方法,主要使用 MongoTemplate 或 MongoRepository 结合地理空间查询功能:

解决思路:

  1. 首先,确保 MongoDB 服务器支持地理空间索引和查询,并且在集合上创建了地理空间索引。
  2. 使用 GeoJsonPoint 或 Double[] 表示经纬度。
  3. 使用 nearSphere 或 within 等操作符进行地理空间查询。

使用 MongoTemplate 进行地理空间查询:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import java.util.List;


class LocationService {


    @Autowired
    private MongoTemplate mongoTemplate;


    // 查询附近的位置,基于 GeoJsonPoint
    public List<Location> findNearbyLocations(GeoJsonPoint point, double maxDistance) {
        Query query = new Query();
        Criteria criteria = Criteria.where("location").nearSphere(point).maxDistance(maxDistance);
        query.addCriteria(criteria);
        return mongoTemplate.find(query, Location.class);
    }


    // 查询在多边形区域内的位置,基于 GeoJsonPoint
    public List<Location> findLocationsInPolygon(List<GeoJsonPoint> points) {
        Query query = new Query();
        Criteria criteria = Criteria.where("location").within(
                new Polygon(points)
        );
        query.addCriteria(criteria);
        return mongoTemplate.find(query, Location.class);
    }


    // 查询在圆形区域内的位置,基于 Double[] 表示经纬度
    public List<Location> findLocationsInCircle(double[] center, double radius) {
        Query query = new Query();
        Criteria criteria = Criteria.where("location").nearSphere(center).maxDistance(radius);
        query.addCriteria(criteria);
        return mongoTemplate.find(query, Location.class);
    }
}


class Location {
    private String id;
    private GeoJsonPoint location;
    // 请添加 getter 和 setter 方法
}


class Polygon {
    private List<GeoJsonPoint> points;


    public Polygon(List<GeoJsonPoint> points) {
        this.points = points;
    }


    public List<GeoJsonPoint> getPoints() {
        return points;
    }
}

代码解释:


  • findNearbyLocations 方法:
  • 使用 nearSphere 操作符和 maxDistance 来查找距离 point 不超过 maxDistance 的位置。
  • GeoJsonPoint 是一种表示经纬度的标准格式。
  • findLocationsInPolygon 方法:
  • 使用 within 操作符和 Polygon 对象来查找位于多边形区域内的位置。
  • Polygon 类用于封装多边形的顶点。
  • findLocationsInCircle 方法:
  • 使用 nearSphere 和 maxDistance 查找位于圆形区域内的位置,这里使用 Double[] 表示经纬度。

使用 MongoRepository 进行地理空间查询:

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import java.util.List;


interface LocationRepository extends MongoRepository<Location, String> {


    // 查询附近的位置,基于 GeoJsonPoint
    @Query("{ 'location' : { $nearSphere :?0, $maxDistance :?1 } }")
    List<Location> findNearbyLocations(GeoJsonPoint point, double maxDistance);


    // 查询在多边形区域内的位置,基于 GeoJsonPoint
    @Query("{ 'location' : { $geoWithin : { $geometry : { $type : 'Polygon', $coordinates :?0 } } } }")
    List<Location> findLocationsInPolygon(List<List<Double[]>> points);


    // 查询在圆形区域内的位置,基于 Double[] 表示经纬度
    @Query("{ 'location' : { $nearSphere :?0, $maxDistance :?1 } }")
    List<Location> findLocationsInCircle(double[] center, double radius);
}

代码解释:

  • @Query 注解允许使用 MongoDB 的地理空间查询语法。
  • $nearSphere 和 $maxDistance 用于查找附近的位置。
  • $geoWithin 和 $geometry 用于查找在指定几何形状内的位置,这里使用 Polygon 类型和 coordinates 来表示多边形区域。

创建地理空间索引:
在使用上述查询之前,需要在集合上创建地理空间索引:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.GeoSpatialIndex;


class LocationService {


    @Autowired
    private MongoTemplate mongoTemplate;


    public void createGeoIndex() {
        GeoSpatialIndex index = new GeoSpatialIndex("location");
        mongoTemplate.indexOps(Location.class).ensureIndex(index);
    }
}

代码解释:


  • GeoSpatialIndex 用于创建地理空间索引,这里为 location 字段创建索引。
  • mongoTemplate.indexOps(Location.class).ensureIndex(index) 确保索引创建在 Location 集合上。

使用说明:

  • 在 MongoTemplate 中:
  1. 创建 Query 对象和 Criteria 对象。
  2. 使用 nearSpherewithin 等操作符添加地理空间查询条件。
  3. 调用 mongoTemplate.find 方法进行查询。
  • 在 MongoRepository 中:
  1. 使用 @Query 注解,直接使用 MongoDB 的地理空间查询语法。
  • 对于地理空间索引:
  1. 使用 GeoSpatialIndex 创建索引。
  2. 调用 ensureIndex 方法确保索引创建成功。


相关文章