|
| 1 | +=================== |
| 2 | +Search Geospatially |
| 3 | +=================== |
| 4 | + |
| 5 | +.. default-domain:: mongodb |
| 6 | + |
| 7 | +.. contents:: On this page |
| 8 | + :local: |
| 9 | + :backlinks: none |
| 10 | + :depth: 2 |
| 11 | + :class: singlecol |
| 12 | + |
| 13 | +Overview |
| 14 | +-------- |
| 15 | + |
| 16 | +On this page you will learn how to search **geospatial data** with the |
| 17 | +MongoDB Java Driver, and the different geospatial data formats supported by MongoDB. |
| 18 | + |
| 19 | +Geospatial data is data that represents a geographical location on |
| 20 | +the surface of the Earth. Examples of geospatial data include: |
| 21 | + |
| 22 | +- Locations of movie theaters |
| 23 | +- Borders of countries |
| 24 | +- Routes of bicycle rides |
| 25 | +- Dog exercise areas in New York City |
| 26 | + |
| 27 | +Coordinates on Earth |
| 28 | +-------------------- |
| 29 | + |
| 30 | +To store and query your geospatial data in MongoDB, use **GeoJSON**. GeoJSON is |
| 31 | +a data format created by the Internet Engineering Task Force (IETF). |
| 32 | + |
| 33 | +Here is the location of MongoDB headquarters in GeoJSON: |
| 34 | + |
| 35 | +.. code-block:: json |
| 36 | + |
| 37 | + "MongoDB Headquarters" : { |
| 38 | + "type": "point", |
| 39 | + "coordinates": [-73.986805, 40.7620853] |
| 40 | + } |
| 41 | + |
| 42 | +For definitive information on GeoJSON, see the |
| 43 | +:rfc:`official IETF specification <7946>`. |
| 44 | + |
| 45 | +.. external resource |
| 46 | + |
| 47 | +GeoJSON Positions |
| 48 | +~~~~~~~~~~~~~~~~~ |
| 49 | + |
| 50 | +A position represents a single place on Earth, and exists in code as an array |
| 51 | +containing two or three number values: |
| 52 | + |
| 53 | +- Longitude in the first position (required) |
| 54 | +- Latitude in the second position (required) |
| 55 | +- Elevation in the third position (optional) |
| 56 | + |
| 57 | +.. tip:: Longitude then Latitude |
| 58 | + |
| 59 | + GeoJSON orders coordinates as longitude first and latitude second. This may |
| 60 | + be surprising as geographic coordinate system conventions generally list |
| 61 | + latitude first and longitude second. Make sure to check what format any other |
| 62 | + tools you are working with use. Popular tools such as OpenStreetMap and Google |
| 63 | + Maps list coordinates as latitude first and longitude second. |
| 64 | + |
| 65 | +GeoJSON Types |
| 66 | +~~~~~~~~~~~~~ |
| 67 | + |
| 68 | +Your GeoJSON object's type determines its geometric shape. Geometric shapes are |
| 69 | +made up of positions. |
| 70 | + |
| 71 | +Here are some common GeoJSON types and how you can specify them with positions: |
| 72 | + |
| 73 | +- ``Point``: a single position. This could represent the location of a |
| 74 | + `sculpture <https://en.wikipedia.org/wiki/Chicago_Picasso>`__. |
| 75 | +- ``LineString``: an array of two or more positions, thus forming a series of line |
| 76 | + segments. This could represent |
| 77 | + `the route of the Great Wall of China <https://commons.wikimedia.org/wiki/File:GreatWallChina4.png>`__. |
| 78 | +- ``Polygon``: an array of positions in which the first and last |
| 79 | + position are the same, thus enclosing some space. This could represent |
| 80 | + `the land within Vatican City <https://commons.wikimedia.org/wiki/File:Vatican_City_map_EN.png>`__. |
| 81 | + |
| 82 | + |
| 83 | +To learn more about the shapes you can use in MongoDB, see the |
| 84 | +:manual:`GeoJSON manual entry </reference/geojson/>`. |
| 85 | + |
| 86 | +.. external resource |
| 87 | + |
| 88 | +Index |
| 89 | +~~~~~ |
| 90 | + |
| 91 | +To query data stored in the GeoJSON format, add the field containing |
| 92 | +GeoJSON data to a ``2dsphere`` index. The following snippet creates a |
| 93 | +``2dsphere`` index on the ``location.geo`` field using the ``Indexes`` builder: |
| 94 | + |
| 95 | +.. code-block:: java |
| 96 | + |
| 97 | + // <MongoCollection setup code here> |
| 98 | + collection.createIndex(Indexes.geo2dsphere("location.geo")); |
| 99 | + |
| 100 | +For more information on the ``Indexes`` builder, see our |
| 101 | +:doc:`guide on the Indexes builder </fundamentals/builders/indexes>`. |
| 102 | + |
| 103 | +.. guide resource |
| 104 | + |
| 105 | +Coordinates on a 2D Plane |
| 106 | +------------------------- |
| 107 | + |
| 108 | +You can store geospatial data using ``x`` and ``y`` coordinates on |
| 109 | +a two-dimensional Euclidean plane. We refer to coordinates on a two-dimensional |
| 110 | +plane as "legacy coordinate pairs". |
| 111 | + |
| 112 | +Legacy coordinate pairs have the following structure: |
| 113 | + |
| 114 | +.. code-block:: json |
| 115 | + |
| 116 | + "<field name>" : [ x, y ] |
| 117 | + |
| 118 | +Your field should contain an array of two values in which the first represents |
| 119 | +the ``x`` axis value and the second represents the ``y`` axis value. |
| 120 | + |
| 121 | +Index |
| 122 | +~~~~~ |
| 123 | + |
| 124 | +To query data stored as legacy coordinate pairs, you must add the field containing |
| 125 | +legacy coordinate pairs to a ``2d`` index. The following snippet creates a |
| 126 | +``2d`` index on the ``coordinates`` field using the ``Indexes`` builder: |
| 127 | + |
| 128 | +.. code-block:: java |
| 129 | + |
| 130 | + // <MongoCollection setup code here> |
| 131 | + collection.createIndex(Indexes.geo2d("coordinates")); |
| 132 | + |
| 133 | +For more information on the ``Indexes`` builder, see our |
| 134 | +:doc:`guide on the Indexes builder </fundamentals/builders/indexes>`. |
| 135 | + |
| 136 | +For more information on legacy coordinate pairs, see the |
| 137 | +:manual:`MongoDB server manual page on legacy coordinate pairs </geospatial-queries/#legacy-coordinate-pairs>`. |
| 138 | + |
| 139 | +.. external resource |
| 140 | + |
| 141 | +.. note:: Supported Operators |
| 142 | + |
| 143 | + Spherical (``2dsphere``) and flat (``2d``) indexes support some, but |
| 144 | + not all, of the same query operators. For a full list of operators |
| 145 | + and their index compatibility, see the |
| 146 | + :manual:`manual entry for geospatial queries </geospatial-queries/#geospatial-query-operators>`. |
| 147 | + |
| 148 | + .. external resource |
| 149 | + |
| 150 | +Geospatial Queries |
| 151 | +------------------ |
| 152 | + |
| 153 | +Geospatial queries consist of a query operator and GeoJSON shapes as query |
| 154 | +parameters. |
| 155 | + |
| 156 | +Query Operators |
| 157 | +~~~~~~~~~~~~~~~ |
| 158 | + |
| 159 | +To query your geospatial data, use one of the following query operators: |
| 160 | + |
| 161 | +- ``$near`` |
| 162 | +- ``$geoWithin`` |
| 163 | +- ``$nearSphere`` |
| 164 | +- ``$geoIntersects`` *requires a 2dsphere index* |
| 165 | + |
| 166 | +You can specify these query operators in the MongoDB Java driver with the |
| 167 | +``near()``, ``geoWithin()``, ``nearSphere()``, and ``geoIntersects()`` utility |
| 168 | +methods of the ``Filters`` builder class. |
| 169 | + |
| 170 | +For more information on geospatial query operators, see the |
| 171 | +:manual:`manual entry for geospatial queries </geospatial-queries/#geospatial-query-operators>`. |
| 172 | + |
| 173 | +.. external resource |
| 174 | + |
| 175 | +For more information on ``Filters``, see our |
| 176 | +:doc:`guide on the Filters builder </fundamentals/builders/filters>`. |
| 177 | + |
| 178 | +Query Parameters |
| 179 | +~~~~~~~~~~~~~~~~ |
| 180 | + |
| 181 | +To specify a shape to use in a geospatial query, use the |
| 182 | +``Position``, ``Point``, ``LineString``, and ``Polygon`` classes of the MongoDB |
| 183 | +Java driver. |
| 184 | + |
| 185 | +For a full list of the GeoJSON shapes available in the MongoDB Java driver, see the |
| 186 | +:java-docs:`GeoJSON package </apidocs/mongodb-driver-core/com/mongodb/client/model/geojson/package-summary.html>`. |
| 187 | + |
| 188 | +.. external resource |
| 189 | + |
| 190 | +Examples |
| 191 | +-------- |
| 192 | + |
| 193 | +The following examples use the MongoDB Atlas sample dataset. You can learn how |
| 194 | +to set up your own free-tier Atlas cluster and how to load the sample dataset |
| 195 | +in our :doc:`quick start guide </quick-start>`. |
| 196 | + |
| 197 | +The examples use the ``theaters`` collection in the ``sample_mflix`` database |
| 198 | +from the sample dataset. The ``theaters`` collection contains a ``2dsphere`` index |
| 199 | +on the ``location.geo`` field. |
| 200 | + |
| 201 | +The examples require the following imports: |
| 202 | + |
| 203 | +.. literalinclude:: /includes/fundamentals/code-snippets/Geo.java |
| 204 | + :language: java |
| 205 | + :dedent: |
| 206 | + :start-after: begin exampleImports |
| 207 | + :end-before: end exampleImports |
| 208 | + |
| 209 | +You can find the |
| 210 | +`source code for the examples on Github here <https://github.com/mongodb/docs-java/blob/master/source/includes/fundamentals/code-snippets/Geo.java>`__. |
| 211 | + |
| 212 | +.. external resource |
| 213 | + |
| 214 | +Query by Proximity |
| 215 | +~~~~~~~~~~~~~~~~~~ |
| 216 | + |
| 217 | +To search for and return documents from nearest to farthest from a point, use |
| 218 | +the ``near()`` static utility method of the ``Filters`` builder class. The |
| 219 | +``near()`` method constructs a query with the ``$near`` query operator. |
| 220 | + |
| 221 | +The following example queries for theaters between ``10,000`` and ``5,000`` |
| 222 | +meters from the |
| 223 | +`Great Lawn of Central Park <https://en.wikipedia.org/wiki/Great_Lawn_and_Turtle_Pond>`__. |
| 224 | + |
| 225 | +.. literalinclude:: /includes/fundamentals/code-snippets/Geo.java |
| 226 | + :language: java |
| 227 | + :dedent: |
| 228 | + :start-after: begin findExample |
| 229 | + :end-before: end findExample |
| 230 | + |
| 231 | +The output of the code snippet should look something like this: |
| 232 | + |
| 233 | +.. code-block:: json |
| 234 | + |
| 235 | + {"location": {"address": {"city": "Bronx"}}} |
| 236 | + {"location": {"address": {"city": "New York"}}} |
| 237 | + {"location": {"address": {"city": "New York"}}} |
| 238 | + {"location": {"address": {"city": "Long Island City"}}} |
| 239 | + {"location": {"address": {"city": "New York"}}} |
| 240 | + {"location": {"address": {"city": "Secaucus"}}} |
| 241 | + {"location": {"address": {"city": "Jersey City"}}} |
| 242 | + {"location": {"address": {"city": "Elmhurst"}}} |
| 243 | + {"location": {"address": {"city": "Flushing"}}} |
| 244 | + {"location": {"address": {"city": "Flushing"}}} |
| 245 | + {"location": {"address": {"city": "Flushing"}}} |
| 246 | + {"location": {"address": {"city": "Elmhurst"}}} |
| 247 | + |
| 248 | +.. note:: Fun Fact |
| 249 | + |
| 250 | + MongoDB uses the |
| 251 | + :manual:`same reference system </reference/glossary/#std-term-WGS84>` |
| 252 | + as GPS satellites to calculate geometries over the Earth. |
| 253 | + |
| 254 | +For more information on the ``$near`` operator, see |
| 255 | +:manual:`the reference documentation for $near </reference/operator/query/near/#mongodb-query-op.-near>`. |
| 256 | + |
| 257 | +For more information on ``Filters``, |
| 258 | +:doc:`see our guide on the Filters builder </fundamentals/builders/filters>`. |
| 259 | + |
| 260 | +Query Within a Range |
| 261 | +~~~~~~~~~~~~~~~~~~~~ |
| 262 | + |
| 263 | +To search for geospatial data within a specified shape use the ``geoWithin()`` |
| 264 | +static utility method of the ``Filters`` builder class. The ``geoWithin()`` |
| 265 | +method constructs a query with the ``$geoWithin`` query operator. |
| 266 | + |
| 267 | +.. figure:: /includes/figures/geo_geometry.png |
| 268 | + :alt: Area of Long Island we are searching for movie theaters |
| 269 | + |
| 270 | +The following example searches for movie theaters in the section of Long Island |
| 271 | +described in the figure above. |
| 272 | + |
| 273 | +.. _example_range_query: |
| 274 | + |
| 275 | +.. literalinclude:: /includes/fundamentals/code-snippets/Geo.java |
| 276 | + :language: java |
| 277 | + :dedent: |
| 278 | + :start-after: begin rangeExample |
| 279 | + :end-before: end rangeExample |
| 280 | + |
| 281 | +The output of the code snippet should look something like this: |
| 282 | + |
| 283 | +.. code-block:: json |
| 284 | + |
| 285 | + {"location": {"address": {"city": "Baldwin"}}} |
| 286 | + {"location": {"address": {"city": "Levittown"}}} |
| 287 | + {"location": {"address": {"city": "Westbury"}}} |
| 288 | + {"location": {"address": {"city": "Mount Vernon"}}} |
| 289 | + {"location": {"address": {"city": "Massapequa"}}} |
| 290 | + |
| 291 | + |
| 292 | +For more information on the ``$geoWithin`` operator, see the |
| 293 | +:manual:`reference documentation for $geoWithin </reference/operator/query/geoWithin/>` |
| 294 | + |
| 295 | +.. external resource |
| 296 | + |
| 297 | +For more information on the operators you can use in your query, see the |
| 298 | +:manual:`MongoDB server manual page on geospatial query operators </geospatial-queries/index.html>` |
| 299 | + |
| 300 | +.. external resource |
0 commit comments