|
| 1 | +--- |
| 2 | +title: Support for Geospatial Queries |
| 3 | +titleSuffix: Introducing support for geospatial queries on vCore based Azure Cosmos DB for MongoDB. |
| 4 | +description: Introducing support for geospatial queries on vCore based Azure Cosmos DB for MongoDB. |
| 5 | +author: suvishodcitus |
| 6 | +ms.author: suvishod |
| 7 | +ms.reviewer: abramees |
| 8 | +ms.service: azure-cosmos-db |
| 9 | +ms.subservice: mongodb-vcore |
| 10 | +ms.topic: conceptual |
| 11 | +ms.date: 07/31/2024 |
| 12 | +--- |
| 13 | + |
| 14 | +# Support for Geospatial Queries |
| 15 | + |
| 16 | +[!INCLUDE[MongoDB (vCore)](~/reusable-content/ce-skilling/azure/includes/cosmos-db/includes/appliesto-mongodb-vcore.md)] |
| 17 | + |
| 18 | +Geospatial data can now be stored and queried using vCore-based Azure Cosmos DB for MongoDB. This enhancement provides powerful tools to manage and analyze spatial data, enabling a wide range of applications such as real-time location tracking, route optimization, and spatial analytics. |
| 19 | + |
| 20 | +Here’s a quick overview of the geospatial commands and operators now supported: |
| 21 | + |
| 22 | +## Geospatial Query Operators |
| 23 | + |
| 24 | +### **$geoIntersects** |
| 25 | +Selects documents where a specified geometry intersects with the documents' geometry. Useful for finding documents that share any portion of space with a given geometry. |
| 26 | + |
| 27 | + ```json |
| 28 | + db.collection.find({ |
| 29 | + location: { |
| 30 | + $geoIntersects: { |
| 31 | + $geometry: { |
| 32 | + type: "<GeoJSON object type>", |
| 33 | + coordinates: [[[...], [...], [...], [...]]] |
| 34 | + } |
| 35 | + } |
| 36 | + } |
| 37 | + }) |
| 38 | + ``` |
| 39 | + |
| 40 | +### **$geoWithin** |
| 41 | +Selects documents with geospatial data that exists entirely within a specified shape. This operator is used to find documents within a defined area. |
| 42 | + |
| 43 | + ```json |
| 44 | + db.collection.find({ |
| 45 | + location: { |
| 46 | + $geoWithin: { |
| 47 | + $geometry: { |
| 48 | + type: "Polygon", |
| 49 | + coordinates: [[[...], [...], [...], [...]]] |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | + }) |
| 54 | + ``` |
| 55 | + |
| 56 | +### **$box** |
| 57 | +Defines a rectangular area using two coordinate pairs (bottom-left and top-right corners). Used with the `$geoWithin` operator to find documents within this rectangle. For example, finding all locations within a rectangular region on a map. |
| 58 | + |
| 59 | + ```json |
| 60 | + db.collection.find({ |
| 61 | + location: { |
| 62 | + $geoWithin: { |
| 63 | + $box: [[lowerLeftLong, lowerLeftLat], [upperRightLong, upperRightLat]] |
| 64 | + } |
| 65 | + } |
| 66 | + }) |
| 67 | + ``` |
| 68 | + |
| 69 | +### **$center** |
| 70 | +Defines a circular area using a center point and a radius in radians. Used with the `$geoWithin` operator to find documents within this circle. |
| 71 | + |
| 72 | + ```json |
| 73 | + db.collection.find({ |
| 74 | + location: { |
| 75 | + $geoWithin: { |
| 76 | + $center: [[longitude, latitude], radius] |
| 77 | + } |
| 78 | + } |
| 79 | + }) |
| 80 | + ``` |
| 81 | + |
| 82 | +### **$centerSphere** |
| 83 | +Similar to `$center`, but defines a spherical area using a center point and a radius in radians. Useful for spherical geometry calculations. |
| 84 | + |
| 85 | + ```json |
| 86 | + db.collection.find({ |
| 87 | + location: { |
| 88 | + $geoWithin: { |
| 89 | + $centerSphere: [[longitude, latitude], radius] |
| 90 | + } |
| 91 | + } |
| 92 | + }) |
| 93 | + ``` |
| 94 | + |
| 95 | +### **$geometry** |
| 96 | +Specifies a GeoJSON object to define a geometry. Used with geospatial operators to perform queries based on complex shapes. |
| 97 | + |
| 98 | + ```json |
| 99 | + db.collection.find({ |
| 100 | + location: { |
| 101 | + $geoIntersects: { |
| 102 | + $geometry: { |
| 103 | + type: "<GeoJSON object type>", |
| 104 | + coordinates: [longitude, latitude] |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | + }) |
| 109 | + ``` |
| 110 | + |
| 111 | +### **$maxDistance** |
| 112 | +Specifies the maximum distance from a point for a geospatial query. Used with `$near` and `$nearSphere` operators. For example, finding all locations within 2 km of a given point. |
| 113 | + |
| 114 | + ```json |
| 115 | + db.collection.find({ |
| 116 | + location: { |
| 117 | + $near: { |
| 118 | + $geometry: { |
| 119 | + type: "Point", |
| 120 | + coordinates: [longitude, latitude] |
| 121 | + }, |
| 122 | + $maxDistance: distance |
| 123 | + } |
| 124 | + } |
| 125 | + }) |
| 126 | + ``` |
| 127 | + |
| 128 | +### **$minDistance** |
| 129 | +Specifies the minimum distance from a point for a geospatial query. Used with `$near` and `$nearSphere` operators. |
| 130 | + |
| 131 | + ```json |
| 132 | + db.collection.find({ |
| 133 | + location: { |
| 134 | + $near: { |
| 135 | + $geometry: { |
| 136 | + type: "Point", |
| 137 | + coordinates: [longitude, latitude] |
| 138 | + }, |
| 139 | + $minDistance: distance |
| 140 | + } |
| 141 | + } |
| 142 | + }) |
| 143 | + ``` |
| 144 | + |
| 145 | +### **$polygon** |
| 146 | +Defines a polygon using an array of coordinate pairs. Used with the `$geoWithin` operator to find documents within this polygon. |
| 147 | + |
| 148 | + ```json |
| 149 | + db.collection.find({ |
| 150 | + location: { |
| 151 | + $geoWithin: { |
| 152 | + $geometry: { |
| 153 | + type: "Polygon", |
| 154 | + coordinates: [[[...], [...], [...], [...]]] |
| 155 | + } |
| 156 | + } |
| 157 | + } |
| 158 | + }) |
| 159 | + ``` |
| 160 | + |
| 161 | +### **$near** |
| 162 | +Finds documents that are near a specified point. Returns documents sorted by distance from the point. For example, finding the nearest restaurants to a user's location. |
| 163 | + |
| 164 | + ```json |
| 165 | + db.collection.find({ |
| 166 | + location: { |
| 167 | + $near: { |
| 168 | + $geometry: { |
| 169 | + type: "Point", |
| 170 | + coordinates: [longitude, latitude] |
| 171 | + }, |
| 172 | + $maxDistance: distance |
| 173 | + } |
| 174 | + } |
| 175 | + }) |
| 176 | + ``` |
| 177 | + |
| 178 | + |
| 179 | +### **$nearSphere** |
| 180 | +Similar to `$near`, but performs calculations on a spherical surface. Useful for more accurate distance calculations on the Earth's surface. |
| 181 | + |
| 182 | + ```json |
| 183 | + db.collection.find({ |
| 184 | + location: { |
| 185 | + $nearSphere: { |
| 186 | + $geometry: { |
| 187 | + type: "Point", |
| 188 | + coordinates: [longitude, latitude] |
| 189 | + }, |
| 190 | + $maxDistance: distance |
| 191 | + } |
| 192 | + } |
| 193 | + }) |
| 194 | + ``` |
| 195 | + |
| 196 | +## Geospatial Aggregation Stage |
| 197 | + |
| 198 | +### **$geoNear** |
| 199 | +Performs a geospatial query to return documents sorted by distance from a specified point. Can include additional query criteria and return distance information. |
| 200 | + |
| 201 | + ```json |
| 202 | + db.collection.aggregate([ |
| 203 | + { |
| 204 | + $geoNear: { |
| 205 | + near: { |
| 206 | + type: "Point", |
| 207 | + coordinates: [longitude, latitude] |
| 208 | + }, |
| 209 | + distanceField: "distance", |
| 210 | + spherical: true |
| 211 | + } |
| 212 | + } |
| 213 | + ]) |
| 214 | + ``` |
| 215 | + |
| 216 | + |
| 217 | +## Considerations and Unsupported Capabilities |
| 218 | + |
| 219 | + |
| 220 | +* Currently, querying with a single-ringed GeoJSON polygon whose area exceeds a single hemisphere isn't supported. In such cases, Mongo vCore returns the following error message: |
| 221 | + ```json |
| 222 | + Error: Custom CRS for big polygon is not supported yet. |
| 223 | + ``` |
| 224 | +* A composite index using a regular index and geospatial index isn't allowed. For example: |
| 225 | + ```json |
| 226 | + db.collection.createIndex({a: "2d", b: 1}); |
| 227 | + Error: Compound 2d indexes are not supported yet |
| 228 | + ``` |
| 229 | +* Polygons with holes are currently not supported for use with $geoWithin queries. Although inserting a polygon with holes is not restricted, it eventually fails with the following error message: |
| 230 | + |
| 231 | + ```json |
| 232 | + Error: $geoWithin currently doesn't support polygons with holes |
| 233 | + ``` |
| 234 | +* The key field is always required in the $geoNear aggregation stage. If the key field is missing, the following error occurs: |
| 235 | + |
| 236 | + ```json |
| 237 | + Error: $geoNear requires a 'key' option as a String |
| 238 | + ``` |
| 239 | +* The `$geoNear`, `$near`, and `$nearSphere` stages don't have strict index requirements, so these queries wouldn't fail if an index is missing. |
| 240 | + |
| 241 | +## Related content |
| 242 | + |
| 243 | +- Read more about [feature compatibility with MongoDB.](compatibility.md) |
| 244 | +- Review options for [migrating from MongoDB to Azure Cosmos DB for MongoDB vCore.](how-to-migrate-native-tools.md) |
0 commit comments