Skip to content

Commit b5fead2

Browse files
geospatial page (#142)
* geospatial page writing code examples DOCSP-13839: geospatial search page in progress rst wip rewrite rewrite move and expose in toc additional resources proofread * clear errors * code formatting * make enumeration read more cleanly * more feedback * feedback * lanuage * proofread * this -> the * suggestion Co-authored-by: Nora Reidy <[email protected]>
1 parent d038230 commit b5fead2

File tree

4 files changed

+359
-0
lines changed

4 files changed

+359
-0
lines changed

snooty.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ sharedinclude_root = "https://raw.githubusercontent.com/10gen/docs-shared/main/"
1515

1616
[constants]
1717
driver-long = "MongoDB Go Driver"
18+
driver-short = "Go driver"
1819
docs-branch = "master" # always set this to the docs branch (i.e. master, 1.7, 1.8, etc.)
1920
version = "v1.10.1" # always set this to the driver branch (i.e. v1.7.0, v1.8.0, etc.)
2021
example = "https://raw.githubusercontent.com/mongodb/docs-golang/{+docs-branch+}/source/includes/usage-examples/code-snippets"

source/fundamentals.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Fundamentals
2020
/fundamentals/gridfs
2121
/fundamentals/time-series
2222
/fundamentals/encrypt-fields
23+
/fundamentals/geo
2324

2425
..
2526
/fundamentals/enterprise-auth

source/fundamentals/geo.txt

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
.. _golang-geo:
2+
3+
=========================
4+
Work with Geospatial Data
5+
=========================
6+
7+
.. default-domain:: mongodb
8+
9+
.. contents:: On this page
10+
:local:
11+
:backlinks: none
12+
:depth: 2
13+
:class: singlecol
14+
15+
Overview
16+
--------
17+
18+
In this guide, you can learn how to work with **geospatial data**; data formats,
19+
indexes, and queries. Geospatial
20+
data represents a geographic location on the surface of the Earth, or data
21+
on a Euclidean plane.
22+
23+
Examples of geospatial data include:
24+
25+
- Locations of movie theaters
26+
- Borders of countries
27+
- Routes of bicycle rides
28+
- Dog exercise areas in New York City
29+
- Points on a graph
30+
31+
Store Geospatial Data
32+
---------------------
33+
34+
All geospatial data in MongoDB is stored in one of the following formats:
35+
36+
- GeoJSON, a format that represents geospatial data on an earth-like
37+
sphere.
38+
39+
- Legacy Coordinate Pair, a format that represents geospatial data
40+
on a Euclidean plane.
41+
42+
GeoJSON
43+
~~~~~~~
44+
45+
Use GeoJSON to store data that represents geospatial information on
46+
an earth-like sphere. GeoJSON is composed of one or more **positions**
47+
and a **type**.
48+
49+
Positions
50+
`````````
51+
52+
A position represents a single place on Earth and exists in code as an array
53+
containing the following values:
54+
55+
- Longitude in the first position (required)
56+
- Latitude in the second position (required)
57+
- Elevation in the third position (optional)
58+
59+
The following is the **position** of the MongoDB Headquarters in
60+
New York City, NY.
61+
62+
.. code-block:: go
63+
:copyable: False
64+
65+
[]float64{-73.986805, 40.7620853}
66+
67+
.. important:: Longitude then Latitude
68+
69+
GeoJSON orders coordinates as **longitude** first and **latitude** second.
70+
This may be surprising as geographic coordinate system conventions generally list
71+
latitude first and longitude second. Make sure to check what format any other
72+
tools you are working with use. Popular tools such as OpenStreetMap and Google
73+
Maps list coordinates as latitude first and longitude second.
74+
75+
76+
Types
77+
`````
78+
79+
Your GeoJSON object's type determines the geometric shape it represents. Geometric shapes are
80+
made up of positions.
81+
82+
Here are some common GeoJSON types and how you can specify them with positions:
83+
84+
- ``Point``: a single position. The following ``Point`` represents the location of
85+
the MongoDB Headquarters:
86+
87+
.. code-block:: go
88+
:copyable: False
89+
90+
bson.D{
91+
{"name", "MongoDB HQ"},
92+
{"location", bson.D{
93+
{"type", "Point"},
94+
{"coordinates", []float64{-73.986805, 40.7620853}},
95+
}},
96+
}
97+
98+
- ``LineString``: an array of two or more positions that forms a series of line
99+
segments. A ``LineString`` can represent a path, route, border, or any other linear
100+
geospatial data. The following ``LineString`` represents a segment of
101+
`the Great Wall of China <https://commons.wikimedia.org/wiki/File:GreatWallChina4.png>`__:
102+
103+
.. code-block:: go
104+
:copyable: False
105+
106+
bson.D{
107+
{"name", "Great Wall of China"},
108+
{"location", bson.D{
109+
{"type", "LineString"},
110+
{"coordinates", [][]float64{
111+
{116.572, 40.430},
112+
{116.570, 40.434},
113+
{116.567, 40.436},
114+
{116.566, 40.441},
115+
}}},
116+
},
117+
}
118+
119+
- ``Polygon``: an array of positions in which the first and last
120+
position are the same and enclose some space. The following
121+
``Polygon`` represents `the land within Vatican City
122+
<https://commons.wikimedia.org/wiki/File:Vatican_City_map_EN.png>`__:
123+
124+
.. code-block:: go
125+
:copyable: False
126+
127+
bson.D{
128+
{"name", "Vatican City"},
129+
{"location", bson.D{
130+
{"type", "Polygon"},
131+
{"coordinates", [][][]float64{{
132+
{116.572, 40.430},
133+
{116.570, 40.434},
134+
{116.567, 40.436},
135+
{116.572, 40.430},
136+
}}},
137+
}},
138+
}
139+
140+
141+
To learn more about the GeoJSON types you can use in MongoDB, see the
142+
:manual:`GeoJSON manual entry </reference/geojson/>`.
143+
144+
For definitive information on GeoJSON, see the
145+
`official IETF specification <https://datatracker.ietf.org/doc/html/rfc7946>`__.
146+
147+
Legacy Coordinate Pairs
148+
~~~~~~~~~~~~~~~~~~~~~~~
149+
150+
Use legacy coordinate pairs to store data that represents geospatial information
151+
on a two-dimensional Euclidean plane.
152+
153+
154+
Your field should contain an array of two values in which the first represents
155+
the ``x`` axis value and the second represents the ``y`` axis value.
156+
157+
.. code-block:: json
158+
:copyable: False
159+
160+
bson.D{{"center", []int16{0, 0}}}
161+
162+
163+
For more information on legacy coordinate pairs, see the
164+
:manual:`MongoDB server manual page on legacy coordinate pairs </geospatial-queries/#legacy-coordinate-pairs>`.
165+
166+
.. _golang-geospatial-indexes:
167+
168+
Geospatial Indexes
169+
------------------
170+
171+
To enable querying for geosptial data, you must first create a supporting
172+
index. The following index types that enable geospatial queries:
173+
174+
175+
- ``2dsphere`` for GeoJSON data
176+
- ``2d`` for legacy coordinate pairs
177+
178+
2dsphere
179+
~~~~~~~~
180+
To query data stored in the GeoJSON format, add the field containing
181+
both the ``type`` and ``coordinates`` to a ``2dsphere`` index. The
182+
following snippet creates a ``2dsphere`` index on the ``location`` field:
183+
184+
.. code-block:: go
185+
186+
indexModel := mongo.IndexModel{
187+
Keys: bson.D{{"location", "2dsphere"}},
188+
}
189+
190+
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
191+
if err != nil {
192+
panic(err)
193+
}
194+
195+
196+
2d
197+
~~
198+
To query data stored as legacy coordinate pairs, you must add the field containing
199+
legacy coordinate pairs to a ``2d`` index. The following snippet creates a
200+
``2d`` index on the ``coordinates`` field:
201+
202+
.. code-block:: go
203+
204+
indexModel := mongo.IndexModel{
205+
Keys: bson.D{{"location.coordinates", "2d"}},
206+
}
207+
208+
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
209+
if err != nil {
210+
panic(err)
211+
}
212+
213+
Geospatial Queries
214+
------------------
215+
216+
To perform a geospatial query, create a query filter with a field name and a geospatial
217+
query operator. You can specify additional options for certain geospatial query operators
218+
to limit the documents returned.
219+
220+
If you have not done so, you must :ref:`create a geospatial index <golang-geospatial-indexes>`
221+
to enable geospatial queries.
222+
223+
.. tip:: Supported Operators
224+
225+
Spherical (``2dsphere``) and flat (``2d``) indexes support some, but
226+
not all, of the same query operators. For a full list of operators
227+
and their index compatibility, see the
228+
:manual:`manual entry for geospatial queries </geospatial-queries/#geospatial-query-operators>`.
229+
230+
Query Operators
231+
~~~~~~~~~~~~~~~
232+
233+
To query your geospatial data, use one of the following query operators:
234+
235+
- ``$near``
236+
- ``$geoWithin``
237+
- ``$nearSphere``
238+
- ``$geoIntersects`` *requires a 2dsphere index*
239+
240+
When using the ``$near`` operator, you can specify the following distance operators:
241+
242+
- ``$minDistance``
243+
- ``$maxDistance``
244+
245+
When using the ``$geoWithin`` operator, you can specify the following shape operators:
246+
247+
- ``$box``
248+
- ``$polygon``
249+
- ``$center``
250+
- ``$centerSphere``
251+
252+
For more information on geospatial query operators, see the
253+
:manual:`manual entry for geospatial queries </geospatial-queries/#geospatial-query-operators>`.
254+
255+
Examples
256+
--------
257+
258+
The following examples use the MongoDB Atlas sample dataset. You can load sample datasets into
259+
your database on the free tier of MongoDB Atlas by following the :atlas:`Get Started with Atlas Guide
260+
</getting-started/#atlas-getting-started>` or you can :guides:`import the sample dataset into a local MongoDB instance
261+
</server/import/>`.
262+
263+
The examples use the ``theaters`` collection in the ``sample_mflix`` database
264+
from the sample dataset. The ``theaters`` collection contains a ``2dsphere`` index
265+
on the ``location.geo`` field.
266+
267+
Query by Proximity
268+
~~~~~~~~~~~~~~~~~~
269+
270+
The following example queries for documents with a ``location.geo`` field
271+
within 1000 meters of the MongoDB Headquarters in New York City, NY. It returns documents
272+
from nearest to farthest.
273+
274+
.. io-code-block::
275+
276+
.. input::
277+
:language: go
278+
279+
mongoDBHQ := bson.D{{"type", "Point"}, {"coordinates", []float64{-73.986805, 40.7620853}}}
280+
281+
filter := bson.D{
282+
{"location.geo", bson.D{
283+
{"$near", bson.D{
284+
{"$geometry", mongoDBHQ},
285+
{"$maxDistance", 1000},
286+
}},
287+
}},
288+
}
289+
var places []bson.D
290+
output, err := coll.Find(context.TODO(), filter)
291+
if err = output.All(context.TODO(), &places); err != nil {
292+
panic(err)
293+
}
294+
fmt.Println(places)
295+
296+
.. output::
297+
:language: json
298+
299+
[
300+
[{_id ObjectID(...)} {theaterId 1908} {location [{address [...]} {geo [{type Point} {coordinates [-73.983487 40.76078]}]}]}]
301+
[{_id ObjectID(...)} {theaterId 1448} {location [{address [...]} {geo [{type Point} {coordinates [-73.982094 40.76988]}]}]}]
302+
]
303+
304+
305+
Query Within a Range
306+
~~~~~~~~~~~~~~~~~~~~
307+
308+
The following example queries for documents with a ``location.geo`` field
309+
no closer than 2000 meters and no farther than 3000 meters of the MongoDB
310+
Headquarters in New York City, NY. It returns documents from nearest to farthest.
311+
312+
.. io-code-block::
313+
314+
.. input::
315+
:language: go
316+
317+
mongoDBHQ := bson.D{{"type", "Point"}, {"coordinates", []float64{-73.986805, 40.7620853}}}
318+
319+
filter := bson.D{
320+
{"location.geo",
321+
bson.D{
322+
{"$nearSphere", bson.D{
323+
{"$geometry", MongoDBHQ},
324+
{"$minDistance", 2000},
325+
{"$maxDistance", 3000},
326+
}},
327+
}},
328+
}
329+
var places bson.D
330+
err := coll.Find(context.TODO(), filter).Decode(&places)
331+
if err != nil {
332+
panic(err)
333+
}
334+
fmt.Println(places)
335+
336+
.. output::
337+
:language: json
338+
339+
[[{_id ObjectID(...)} {theaterId 482} {location [...]} {geo [{type Point} {coordinates [-73.99295 40.74194]}]}]}]]
340+
341+
Additional Resources
342+
--------------------
343+
344+
- For more information about working with geospatial data, see the
345+
:ref:`manual entry for geospatial data <geo-overview-location-data>`.
346+
347+
- For more information about supported GeoJSON types, see the the
348+
:manual:`GeoJSON manual entry </reference/geojson/>`.
349+
350+
- For more information about geospatial query operators, see the
351+
:manual:`manual entry for geospatial queries </geospatial-queries/#geospatial-query-operators>`.
352+
353+
- For more information about working with indexes with the {+driver-short+}, see the
354+
:ref:`index guide <golang-indexes>`.
355+
356+

source/includes/fundamentals-sections.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Fundamentals section:
1111
- :ref:`Construct Indexes <golang-indexes>`
1212
- :ref:`Use a Time Series Collection <golang-time-series>`
1313
- :ref:`Encrypt Fields <golang-fle>`
14+
- :ref:`Work with Geospatial Data <golang-geo>`
1415

1516
.. - :doc:`Use the Driver's Data Formats </fundamentals/data-formats>`
1617
.. - :doc:`Specify Collations </fundamentals/collations>`

0 commit comments

Comments
 (0)