@@ -34,9 +34,9 @@ to the database in pipeline stages.
3434Sample Data
3535~~~~~~~~~~~
3636
37- The examples in this guide use the ``Movie`` model, which represents the
38- ``sample_mflix.movies `` collection from the :atlas:`Atlas sample datasets </sample-data>`.
39- The ``Movie`` model class has the following definition :
37+ The examples in this guide use the ``Movie`` and ``Theater`` models, which
38+ represent collections in the ``sample_mflix`` database from the :atlas:`Atlas sample datasets </sample-data>`.
39+ The model classes have the following definitions :
4040
4141.. code-block:: python
4242
@@ -58,6 +58,30 @@ The ``Movie`` model class has the following definition:
5858
5959 def __str__(self):
6060 return self.title
61+
62+ class Theater(models.Model):
63+ theaterId = models.IntegerField(default=0)
64+ location = EmbeddedModelField(Location)
65+ objects = MongoManager()
66+
67+ class Meta:
68+ db_table = "theaters"
69+
70+ def __str__(self):
71+ return self.title
72+
73+ class Location(models.Model):
74+ geo = EmbeddedModelField(Geo)
75+
76+ class Meta:
77+ abstract = True
78+
79+ class Geo(models.Model):
80+ type = models.CharField(max_length=100)
81+ coordinates = ArrayField(models.DecimalField(max_digits=9, decimal_places=6), blank=True)
82+
83+ class Meta:
84+ abstract = True
6185
6286To learn how to create a Django application that uses a similar ``Movie``
6387model to interact with MongoDB documents, visit the :ref:`django-get-started`
@@ -263,6 +287,75 @@ actions:
263287Query Geospatial Data
264288~~~~~~~~~~~~~~~~~~~~~
265289
290+ You can use the ``raw_aggregate()`` method to run queries
291+ on fields containing geospatial data. Geospatial data represents
292+ a geographic location on the surface of the Earth or on a
293+ Euclidean plane.
294+
295+ To run a geospatial query, create a ``2d`` or ``2dsphere`` index on fields
296+ containing geospatial data. Then, specify one of the following
297+ query operators in an aggregation pipeline parameter to
298+ the ``raw_aggregate()`` method:
299+
300+ - ``$near``
301+ - ``$geoWithin``
302+ - ``$nearSphere``
303+ - ``$geoIntersects``
304+
305+ .. important::
306+
307+ You cannot use {+django-odm+} to create ``2d`` or ``2dsphere`` indexes.
308+
309+ For instructions on using the PyMongo driver to create geospatial
310+ indexes, see :driver:`Geospatial Indexes
311+ </python/pymongo-driver/current/indexes/geospatial-index/>` in
312+ the PyMongo documentation.
313+
314+ For instructions on using the MongoDB Shell to create geospatial
315+ indexes, see :manual:`Geospatial Indexes </core/indexes/index-types/index-geospatial/>`
316+ in the {+mdb-server+} manual.
317+
318+ This example runs a geospatial query by passing the ``$near`` pipeline
319+ stage to the ``raw_aggregate()`` method. The code queries for documents
320+ in which the ``location.geo`` field stores a location within ``1000`` meters
321+ of the MongoDB Headquarters in New York City, NY:
322+
323+ .. io-code-block::
324+ :copyable: true
325+
326+ .. input::
327+ :language: python
328+
329+ theaters = Theater.objects.raw_aggregate([
330+ {
331+ "$match": {
332+ "location.geo": {
333+ "$near": {
334+ "$geometry": {
335+ "type": "Point",
336+ "coordinates": [-73.986805, 40.7620853]
337+ },
338+ "$maxDistance": 1000
339+ }
340+ }
341+ }
342+ },
343+ {
344+ "$project": {
345+ "name": 1,
346+ "location": 1
347+ }
348+ }
349+ ])
350+
351+ for t in theaters:
352+ print(f"Theater: {t.name}, location: {t.location}\n")
353+
354+ .. output::
355+ :language: none
356+ :visible: false
357+
358+ TODO
266359
267360Additional Information
268361----------------------
@@ -276,4 +369,8 @@ To learn more about running aggregation operations, see
276369in the {+mdb-server+} manual.
277370
278371To learn more about Atlas Search, see :atlas:`Atlas Search </atlas-search>`
279- in the Atlas documentation.
372+ in the Atlas documentation.
373+
374+ To learn more about running geospatial queries, see
375+ :manual:`Geospatial Queries </geospatial-queries/>`
376+ in the {+mdb-server+} manual.
0 commit comments