如何为DocumentDbRepositories声明地理空间JSON实体并适配Spring Boot API
Got it, let's break this down step by step — I've worked through this exact scenario with Azure Cosmos DB (the successor to DocumentDB) and Spring Boot, so here's a straightforward implementation:
1. Define Your Entity Classes with Geospatial Support
First, we need to model your desired JSON structure into Java classes, and annotate them to let Cosmos DB recognize the geospatial data.
Main Entity (Place.java)
This maps to the top-level JSON structure, with a dedicated field for the GeoJSON Polygon:
import org.springframework.data.annotation.Id; import com.azure.spring.data.cosmos.core.mapping.Container; import com.azure.spring.data.cosmos.core.mapping.Geospatial; import com.azure.spring.data.cosmos.core.mapping.GeospatialType; @Container(containerName = "places") // Name of your Cosmos DB container public class Place { @Id private String id; private String name; private String address; // Mark this field as GeoJSON-type geospatial data @Geospatial(type = GeospatialType.GEO_JSON) private Area area; // Constructors, getters, and setters public Place() {} public Place(String id, String name, String address, Area area) { this.id = id; this.name = name; this.address = address; this.area = area; } // Add all getter/setter methods for the fields here }
GeoJSON Polygon Entity (Area.java)
This class models the nested area object in your desired JSON:
public class Area { // Fixed as "Polygon" for this use case, or make it dynamic if needed private String type = "Polygon"; // GeoJSON coordinates are [longitude, latitude], in a 3D array for Polygons private double[][][] coordinates; // Constructors, getters, and setters public Area() {} public Area(double[][][] coordinates) { this.coordinates = coordinates; } // Add getter/setter methods here }
2. Configure Spring Boot for Cosmos DB Geospatial Support
Update your application.yml (or application.properties) to enable GeoJSON as the default geospatial format for your Cosmos DB connection:
Using application.yml
azure: cosmos: uri: ${COSMOS_DB_URI} # Replace with your Cosmos DB URI key: ${COSMOS_DB_KEY} # Replace with your primary key database: ${COSMOS_DB_DATABASE} # Replace with your database name consistency-level: Session geospatial-config: type: GEO_JSON # Globally set geospatial type to GeoJSON
Using application.properties
azure.cosmos.uri=your-cosmos-db-uri azure.cosmos.key=your-primary-key azure.cosmos.database=your-database-name azure.cosmos.consistency-level=Session azure.cosmos.geospatial-config.type=GEO_JSON
3. Implement the REST API
Create a repository interface to interact with Cosmos DB, then build a controller to return the exact JSON structure you need.
Cosmos DB Repository (PlaceRepository.java)
import org.springframework.data.cosmos.repository.CosmosRepository; // Extend CosmosRepository for CRUD operations on Place entities public interface PlaceRepository extends CosmosRepository<Place, String> { // Add custom spatial queries here if needed, e.g.: // List<Place> findByAreaContains(Point point); }
REST Controller (PlaceController.java)
This controller includes an endpoint to return your sample data, plus an endpoint to fetch existing entities by ID:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import java.util.Optional; @RestController public class PlaceController { private final PlaceRepository placeRepository; // Constructor injection for the repository public PlaceController(PlaceRepository placeRepository) { this.placeRepository = placeRepository; } // Return a sample Place with the exact GeoJSON structure you specified @GetMapping("/places/sample") public Place getSamplePlace() { // Define the Polygon coordinates (remember: [longitude, latitude] order!) double[][][] coordinates = { { {-73.9580, 40.8003}, {-73.9498, 40.7968}, {-73.9737, 40.7648}, {-73.9814, 40.7681}, {-73.9580, 40.8003} } }; Area area = new Area(coordinates); return new Place("dfasdfsfrwrwr", "sample name", "sample adress", area); } // Fetch a Place by its ID from Cosmos DB @GetMapping("/places/{id}") public Optional<Place> getPlaceById(@PathVariable String id) { return placeRepository.findById(id); } }
Key Notes to Remember
- Coordinate Order: GeoJSON requires
[longitude, latitude]— don't mix these up, or your spatial queries will return incorrect results. - Dependency: Make sure you have the latest Spring Data Cosmos DB starter in your
pom.xml:<dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-boot-starter-data-cosmos</artifactId> <version>3.26.0</version> <!-- Use the latest stable version --> </dependency> - Spatial Queries: If you need to run spatial operations (like finding places that contain a point), you can define custom methods in the
PlaceRepositoryusing Cosmos DB's spatial query syntax.
内容的提问来源于stack exchange,提问作者Raj

