最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Spring Data MongoDB進行地理位置相關(guān)查詢的步驟和示例

 更新時間:2025年05月27日 08:51:16   作者:冰糖心書房  
SpringData MongoDB是SpringData技術(shù)封裝了mongodb-driver技術(shù)之后的產(chǎn)物,它可以用更加簡單的方式操作MongoDB,本文給大家介紹了如何使用Spring Data MongoDB進行地理位置相關(guān)查詢的步驟和示例,需要的朋友可以參考下

以下是如何使用 Spring Data MongoDB 進行地理位置相關(guān)查詢的步驟和示例:

核心概念:

  1. GeoJSON 對象: MongoDB 推薦使用 GeoJSON 格式來存儲地理位置數(shù)據(jù)。Spring Data MongoDB 提供了相應(yīng)的 GeoJSON 類型,如 GeoJsonPointGeoJsonPolygonGeoJsonLineString 等。
    • GeoJsonPoint: 表示一個點,例如 [longitude, latitude]。
  2. 地理空間索引 (Geospatial Index): 為了高效地執(zhí)行地理位置查詢,必須在存儲位置數(shù)據(jù)的字段上創(chuàng)建地理空間索引。
    • 2dsphere: 支持球面幾何計算,適用于地球表面的經(jīng)緯度數(shù)據(jù)(推薦)。
    • 2d: 支持平面幾何計算,適用于二維平面上的點。
  3. 查詢操作符: MongoDB 提供了多種地理位置查詢操作符:
    • $near / $nearSphere: 查找靠近某個點的文檔,并按距離排序。
    • $geoWithin: 查找?guī)缀涡螤睿ㄈ缍噙呅巍A形)內(nèi)的文檔。
    • $geoIntersects: 查找與指定 GeoJSON 對象相交的文檔。
    • $centerSphere (與 $geoWithin 結(jié)合使用): 定義一個球心和半徑的圓形區(qū)域進行查詢。

步驟詳解:

步驟 1: 添加依賴

確保你的 pom.xml (Maven) 或 build.gradle (Gradle) 文件中包含 Spring Data MongoDB 的依賴:

<!-- pom.xml (Maven) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

步驟 2: 定義實體 (Entity)

在你的實體類中,使用 org.springframework.data.mongodb.core.geo.GeoJsonPoint (或其他 GeoJSON 類型) 來存儲位置信息。

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexType;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "locations")
public class LocationEntity {

    @Id
    private String id;
    private String name;

    // 存儲經(jīng)緯度信息,并創(chuàng)建 2dsphere 索引
    @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)
    private GeoJsonPoint location; // [longitude, latitude]

    public LocationEntity() {}

    public LocationEntity(String name, GeoJsonPoint location) {
        this.name = name;
        this.location = location;
    }

    // Getters and Setters
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public GeoJsonPoint getLocation() {
        return location;
    }

    public void setLocation(GeoJsonPoint location) {
        this.location = location;
    }

    @Override
    public String toString() {
        return "LocationEntity{" +
               "id='" + id + '\'' +
               ", name='" + name + '\'' +
               ", location=" + (location != null ? location.getCoordinates() : null) +
               '}';
    }
}

注意:

  • @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE) 注解會自動在 location 字段上創(chuàng)建 2dsphere 索引。這是進行地理位置查詢的關(guān)鍵。
  • GeoJSON 點的坐標順序是 [longitude, latitude] (經(jīng)度在前,緯度在后)。

步驟 3: 創(chuàng)建 Repository 接口

Spring Data MongoDB 可以通過方法名派生查詢,或者使用 @Query 注解自定義查詢。

import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;

public interface LocationRepository extends MongoRepository<LocationEntity, String> {

    // 1. 查找靠近某個點的文檔 (使用 $nearSphere)
    // Spring Data 會自動使用 $nearSphere 因為索引是 2dsphere
    // Point 來自 org.springframework.data.geo.Point (x=longitude, y=latitude)
    // Distance 來自 org.springframework.data.geo.Distance
    List<LocationEntity> findByLocationNear(Point point, Distance distance);

    // 也可以只按點查找,不限制距離 (結(jié)果按距離排序)
    List<LocationEntity> findByLocationNear(Point point);

    // 2. 查找在指定多邊形內(nèi)的文檔 (使用 $geoWithin)
    // Polygon 來自 org.springframework.data.geo.Polygon
    List<LocationEntity> findByLocationWithin(Polygon polygon);

    // 3. 查找在指定圓形區(qū)域內(nèi)的文檔 (使用 $geoWithin 和 $centerSphere)
    // Circle 來自 org.springframework.data.geo.Circle
    // Spring Data 會將其轉(zhuǎn)換為 $geoWithin 與 $centerSphere
    List<LocationEntity> findByLocationWithin(org.springframework.data.geo.Circle circle);

    // 4. 查找與指定 GeoJSON 幾何圖形相交的文檔 (使用 $geoIntersects)
    // 需要使用 MongoTemplate 或 @Query 來實現(xiàn)更復(fù)雜的 GeoJSON 相交查詢,
    // 因為派生查詢對 $geoIntersects 的支持有限,尤其是對于復(fù)雜的 GeoJSON 輸入。
    // 但簡單的 Point 相交可以。
    // 對于更復(fù)雜的 GeoJSON (如 Polygon),通常使用 MongoTemplate 或 @Query
    // List<LocationEntity> findByLocationIntersects(GeoJson geometry); // 示例,可能需要自定義實現(xiàn)

}

使用的 Spring Data Geo 類型:

  • org.springframework.data.geo.Point: 用于查詢參數(shù),表示一個點 (x 對應(yīng)經(jīng)度, y 對應(yīng)緯度)。
  • org.springframework.data.geo.Distance: 用于指定距離,可以包含單位 (如 Metrics.KILOMETERS)。
  • org.springframework.data.geo.Polygon: 用于查詢參數(shù),表示一個多邊形。
  • org.springframework.data.geo.Circle: 用于查詢參數(shù),表示一個圓形。
  • org.springframework.data.geo.Box: 用于查詢參數(shù),表示一個矩形。

步驟 4: 使用 Repository 或 MongoTemplate 進行查詢

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import jakarta.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;

@Service
public class LocationService {

    @Autowired
    private LocationRepository locationRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @PostConstruct
    public void init() {
        locationRepository.deleteAll(); // 清理舊數(shù)據(jù)

        // 插入一些示例數(shù)據(jù)
        // 故宮 (116.403963, 39.915119)
        locationRepository.save(new LocationEntity("Forbidden City", new GeoJsonPoint(116.403963, 39.915119)));
        // 天安門廣場 (116.3912757, 39.9037078)
        locationRepository.save(new LocationEntity("Tiananmen Square", new GeoJsonPoint(116.3912757, 39.9037078)));
        // 頤和園 (116.275136, 39.999077)
        locationRepository.save(new LocationEntity("Summer Palace", new GeoJsonPoint(116.275136, 39.999077)));
        // 東方明珠 (121.499718, 31.239703)
        locationRepository.save(new LocationEntity("Oriental Pearl Tower", new GeoJsonPoint(121.499718, 31.239703)));
    }

    public void performGeoQueries() {
        System.out.println("--- Performing Geo Queries ---");

        // 中心點: 北京市中心附近 (例如王府井 116.417427, 39.913904)
        Point centerPoint = new Point(116.417427, 39.913904); // longitude, latitude

        // 1. 查找王府井附近 5 公里內(nèi)的地點
        Distance fiveKilometers = new Distance(5, Metrics.KILOMETERS);
        List<LocationEntity> nearWangfujing = locationRepository.findByLocationNear(centerPoint, fiveKilometers);
        System.out.println("\nLocations near Wangfujing (5km):");
        nearWangfujing.forEach(System.out::println); // 應(yīng)該包含故宮和天安門

        // 2. 查找在指定多邊形內(nèi)的地點 (大致覆蓋北京二環(huán)內(nèi))
        // 注意:多邊形的點必須形成閉合環(huán)路,且第一個點和最后一個點相同
        Polygon beijingRing2 = new Polygon(
                new Point(116.30, 39.85), //西南
                new Point(116.50, 39.85), //東南
                new Point(116.50, 39.95), //東北
                new Point(116.30, 39.95), //西北
                new Point(116.30, 39.85)  //閉合
        );
        List<LocationEntity> withinBeijingRing2 = locationRepository.findByLocationWithin(beijingRing2);
        System.out.println("\nLocations within Beijing Ring 2 (approx):");
        withinBeijingRing2.forEach(System.out::println); // 應(yīng)該包含故宮和天安門

        // 3. 查找在指定圓形區(qū)域內(nèi)的地點 (以故宮為圓心,2公里為半徑)
        Point forbiddenCityCoords = new Point(116.403963, 39.915119);
        Distance twoKilometers = new Distance(2, Metrics.KILOMETERS);
        // 對于2dsphere索引, Circle的距離單位會被正確處理 (例如轉(zhuǎn)換為弧度)
        Circle aroundForbiddenCity = new Circle(forbiddenCityCoords, twoKilometers);
        List<LocationEntity> withinCircle = locationRepository.findByLocationWithin(aroundForbiddenCity);
        System.out.println("\nLocations within 2km of Forbidden City:");
        withinCircle.forEach(System.out::println); // 應(yīng)該包含故宮和天安門

        // 4. 使用 MongoTemplate 進行 $geoIntersects 查詢
        // 定義一個 GeoJsonPolygon (注意點順序,逆時針為外部,順時針為內(nèi)部,但通常簡單多邊形即可)
        // 這里用和上面一樣的多邊形,但用 GeoJsonPolygon
        GeoJsonPolygon queryPolygon = new GeoJsonPolygon(
                new Point(116.30, 39.85),
                new Point(116.50, 39.85),
                new Point(116.50, 39.95),
                new Point(116.30, 39.95),
                new Point(116.30, 39.85)
        );
        Query intersectsQuery = new Query(Criteria.where("location").intersects(queryPolygon));
        List<LocationEntity> intersectingLocations = mongoTemplate.find(intersectsQuery, LocationEntity.class);
        System.out.println("\nLocations intersecting with query polygon (MongoTemplate):");
        intersectingLocations.forEach(System.out::println);


        // 5. 使用 MongoTemplate 進行 $nearSphere 查詢,并指定最小和最大距離
        Query nearQueryWithMinMax = new Query(
            Criteria.where("location")
                    .nearSphere(centerPoint) // 使用 Spring Data Point
                    .minDistance(1000 / 6378137.0) // 最小距離1公里 (轉(zhuǎn)換為弧度,MongoDB $nearSphere 需要弧度或米)
                                                   // 或者直接用米: .minDistance(1000) 如果MongoDB版本支持
                    .maxDistance(5000 / 6378137.0) // 最大距離5公里
                                                   // 或者直接用米: .maxDistance(5000)
        );
        // 如果MongoDB 4.0+ 且 Spring Data MongoDB 2.2+, 可以直接用米
        // Query nearQueryWithMinMaxMeters = new Query(
        // Criteria.where("location")
        // .nearSphere(centerPoint)
        // .minDistance(1000.0) // 1000 meters
        // .maxDistance(5000.0) // 5000 meters
        // );
        // List<LocationEntity> nearWithMinMax = mongoTemplate.find(nearQueryWithMinMaxMeters, LocationEntity.class);
        // System.out.println("\nLocations near Wangfujing (1km-5km, MongoTemplate):");
        // nearWithMinMax.forEach(System.out::println);

        // 對于 $nearSphere,Spring Data 的 Repository 方法中的 Distance 對象會自動處理單位轉(zhuǎn)換。
        // 使用 MongoTemplate 時,對于 $minDistance / $maxDistance:
        // - 如果是 `2dsphere` 索引,MongoDB 期望距離單位是米。
        // - 如果是 `2d` 索引,MongoDB 期望距離單位是索引坐標系的單位。
        // Spring Data MongoDB 3.0+ 配合 MongoDB 4.0+,`nearSphere` 可以直接接受米為單位的 `minDistance`/`maxDistance`。
        // 如果使用較舊版本,可能需要將距離轉(zhuǎn)換為弧度(如示例中除以地球半徑)。
        // 簡單的 findByLocationNear(Point, Distance) 通常是更方便的選擇。
    }
}

運行示例 (在一個 Spring Boot 應(yīng)用中):

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class MongoGeoApplication {

    public static void main(String[] args) {
        SpringApplication.run(MongoGeoApplication.class, args);
    }

    @Bean
    CommandLineRunner runner(LocationService locationService) {
        return args -> {
            locationService.performGeoQueries();
        };
    }
}

總結(jié)與要點:

  1. 實體定義: 使用 GeoJsonPoint (或其他 GeoJson* 類型) 存儲位置,并用 @GeoSpatialIndexed 創(chuàng)建 2dsphere 索引。
  2. 坐標順序: 始終記住 GeoJSON 使用 [longitude, latitude]。Spring Data 的 Point 對象構(gòu)造函數(shù) new Point(x, y) 中 x 是經(jīng)度,y 是緯度。
  3. Repository 查詢: Spring Data Repositories 為常見的地理位置查詢(如 NearWithin)提供了便捷的方法名派生。
  4. MongoTemplate: 對于更復(fù)雜或自定義的地理位置查詢(如 $geoIntersects 配合復(fù)雜 GeoJSON 對象,或需要更精細控制 $nearSphere 的 $minDistance/$maxDistance),可以使用 MongoTemplate
  5. 單位:
    • org.springframework.data.geo.Distance: 允許你指定單位 (如 Metrics.KILOMETERSMetrics.MILES)。Spring Data 會在與 MongoDB 交互時處理轉(zhuǎn)換。
    • MongoDB 的 $nearSphere 和 $centerSphere (用于 2dsphere 索引) 默認使用作為距離單位。
    • 當使用 MongoTemplate 時,需要注意 minDistance/maxDistance 的單位,較新版本的 MongoDB (4.0+) 和 Spring Data MongoDB (2.2+/3.0+) 可以直接使用米。
  6. 性能: 地理空間索引對于查詢性能至關(guān)重要。確保索引已正確創(chuàng)建。

以上就是使用Spring Data MongoDB進行地理位置相關(guān)查詢的步驟和示例的詳細內(nèi)容,更多關(guān)于Spring Data MongoDB地理位置查詢的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • maven項目后出現(xiàn)‘parent.relativePath’ of POM錯誤時的解決方法

    maven項目后出現(xiàn)‘parent.relativePath’ of POM錯誤時的解決方法

    在Springboot項目啟動時,項目報錯‘parent.relativePath’ of POM問題,項目無法正常啟動,本文就來介紹一下解決方法,感興趣的可以了解一下
    2023-10-10
  • Java對MySQL數(shù)據(jù)庫進行連接、查詢和修改操作方法

    Java對MySQL數(shù)據(jù)庫進行連接、查詢和修改操作方法

    這篇文章主要介紹了Java對MySQL數(shù)據(jù)庫進行連接、查詢和修改操作方法,需要的朋友可以參考下
    2017-07-07
  • Spring條件注解@ConditionnalOnClass的原理分析

    Spring條件注解@ConditionnalOnClass的原理分析

    這篇文章主要介紹了Spring條件注解@ConditionnalOnClass的原理分析,所謂@ConditionalOnClass注解,翻譯過來就是基于class的條件,它為所標注的類或方法添加限制條件,當該條件的值為true時,其所標注的類或方法才能生效,需要的朋友可以參考下
    2023-12-12
  • Java/Android引用類型及其使用全面分析

    Java/Android引用類型及其使用全面分析

    下面小編就為大家?guī)硪黄狫ava/Android引用類型及其使用全面分析。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • 在SpringBoot中使用JWT的實現(xiàn)方法

    在SpringBoot中使用JWT的實現(xiàn)方法

    這篇文章主要介紹了在SpringBoot中使用JWT的實現(xiàn)方法,詳細的介紹了什么是JWT和JWT實戰(zhàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • org.apache.ibatis.annotations不存在的問題

    org.apache.ibatis.annotations不存在的問題

    這篇文章主要介紹了org.apache.ibatis.annotations不存在的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java線程池大小的設(shè)置方法實例

    Java線程池大小的設(shè)置方法實例

    線程池的設(shè)置是有方法的,不是憑借簡單的估算來決定的,這篇文章主要給大家介紹了關(guān)于Java線程池大小的設(shè)置方法,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-08-08
  • java虛擬機原理:Class字節(jié)碼二進制文件分析

    java虛擬機原理:Class字節(jié)碼二進制文件分析

    class文件全名稱為Java class文件,主要在平臺無關(guān)性和網(wǎng)絡(luò)移動性方面使Java更適合網(wǎng)絡(luò)。它在平臺無關(guān)性方面的任務(wù)是:為Java程序提供獨立于底層主機平臺的二進制形式的服務(wù)。下面我們來詳細解讀下它吧
    2021-09-09
  • Java?中的?super?關(guān)鍵字用法指南

    Java?中的?super?關(guān)鍵字用法指南

    Java中super關(guān)鍵字用于調(diào)用父類構(gòu)造方法和訪問成員,隱式調(diào)用無參構(gòu)造,顯式調(diào)用有參構(gòu)造,若父類無無參構(gòu)造,子類必須顯式調(diào)用super,以確保正確初始化,本文介紹Java中的super關(guān)鍵字用法指南,感興趣的朋友一起看看吧
    2025-07-07
  • spring boot啟動時mybatis報循環(huán)依賴的錯誤(推薦)

    spring boot啟動時mybatis報循環(huán)依賴的錯誤(推薦)

    今天小編抽時間給大家分享spring boot啟動時mybatis報循環(huán)依賴的錯誤,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-12-12

最新評論

东丽区| 沅陵县| 连南| 新干县| 荣成市| 兴和县| 达尔| 峨边| 蓬莱市| 左权县| 太康县| 观塘区| 岳阳县| 涿鹿县| 溧阳市| 金华市| 中江县| 东源县| 四川省| 道孚县| 普安县| 银川市| 临夏县| 浮山县| 洱源县| 军事| 吉隆县| 本溪市| 万全县| 奉节县| 炉霍县| 宁安市| 辽源市| 家居| 宁晋县| 清水县| 贺州市| 滁州市| 信丰县| 合作市| 乳山市|