From de5d19d2089da4dcd81f4019d1afb275ac66248b Mon Sep 17 00:00:00 2001 From: norareidy Date: Tue, 14 Jan 2025 13:53:25 -0500 Subject: [PATCH 01/14] DOCSP-46322: Raw queries --- snooty.toml | 10 +- source/includes/interact-data/raw-queries.py | 105 +++++++ source/interact-data.txt | 17 ++ source/interact-data/raw-queries.txt | 295 +++++++++++++++++++ 4 files changed, 424 insertions(+), 3 deletions(-) create mode 100644 source/includes/interact-data/raw-queries.py create mode 100644 source/interact-data.txt create mode 100644 source/interact-data/raw-queries.txt diff --git a/snooty.toml b/snooty.toml index 7c56c09..364122d 100644 --- a/snooty.toml +++ b/snooty.toml @@ -5,7 +5,11 @@ intersphinx = [ "https://www.mongodb.com/docs/manual/objects.inv", "https://www.mongodb.com/docs/atlas/objects.inv" ] -# toc_landing_pages = ["/paths/to/pages/that/have/nested/content"] +toc_landing_pages = [ + "/interact-data" +] -# [constants] -# constant = "value" +[constants] +django-odm = "Django MongoDB Backend" +django-api = "https://django-mongodb.readthedocs.io/en/latest/" +mdb-server = "MongoDB Server" diff --git a/source/includes/interact-data/raw-queries.py b/source/includes/interact-data/raw-queries.py new file mode 100644 index 0000000..f965a37 --- /dev/null +++ b/source/includes/interact-data/raw-queries.py @@ -0,0 +1,105 @@ +# start-models +from django.db import models +from django_mongodb_backend.fields import EmbeddedModelField, ArrayField +from django_mongodb_backend.managers import MongoManager + +class Movie(models.Model): + title = models.CharField(max_length=200) + plot = models.TextField(null=True) + runtime = models.IntegerField(default=0) + released = models.DateTimeField("release date", null=True) + awards = EmbeddedModelField(Award) + genres = ArrayField(models.CharField(max_length=100), blank=True) + objects = MongoManager() + + class Meta: + db_table = "movies" + + def __str__(self): + return self.title + +class Theater(models.Model): + theaterId = models.IntegerField(default=0) + objects = MongoManager() + + class Meta: + db_table = "theaters" + + def __str__(self): + return self.title +# end-models + +# start-filter-project +from sample_mflix.models import Movie + +movies = Movie.objects.raw_aggregate([ + {"$match": {"title": "The Parent Trap"}}, + {"$project": { + "title": 1, + "released": 1 + } +}]) + +for m in movies: + print(f"Plot of {m.title}, released on {m.released}: {m.plot}\n") +# end-filter-project + +# start-atlas-search +movies = Movie.objects.raw_aggregate([ + { + "$search": { + "index": "", + "phrase": { + "path": "plot", + "query": "whirlwind romance", + "slop": 3 + }, + "highlight": { + "path": "plot" + } + } + }, + { + "$project": { + "title": 1, + "highlight": {"$meta": "searchHighlights"} + } + } +]) + +for m in movies: + print(f"Title: {m.title}, text match details: {m.highlight}\n") +# end-atlas-search + +# start-geo +chicago_bounds = { + "type": "Polygon", + "coordinates": [[ + [-87.851, 41.976], + [-87.851, 41.653], + [-87.651, 41.653], + [-87.651, 41.976], + [-87.851, 41.976] + ]] +} + +theaters = Theater.objects.raw_aggregate([ + { + "$match": { + "location.geo": { + "$geoWithin": { + "$geometry": chicago_bounds + } + } + } + }, + { + "$project": { + "theaterId": 1 + } + } +]) + +for t in theaters: + print(f"Theater ID: {t.theaterId}") +# end-geo \ No newline at end of file diff --git a/source/interact-data.txt b/source/interact-data.txt new file mode 100644 index 0000000..024caa3 --- /dev/null +++ b/source/interact-data.txt @@ -0,0 +1,17 @@ +.. _django-interact-data: + +================== +Interact with Data +================== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: odm, crud, query + +.. toctree:: + :caption: Interact with Data + + Perform Raw Queries \ No newline at end of file diff --git a/source/interact-data/raw-queries.txt b/source/interact-data/raw-queries.txt new file mode 100644 index 0000000..790c7be --- /dev/null +++ b/source/interact-data/raw-queries.txt @@ -0,0 +1,295 @@ +.. _django-raw-queries: + +============================ +Perform Raw Database Queries +============================ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: number, amount, estimation, code example + +Overview +--------- + +In this guide, you can learn how to use {+django-odm+} to run +raw queries on your MongoDB database. Raw queries allow you to +query the database by using MongoDB's aggregation pipeline syntax +rather than Django methods. + +The Django QuerySet API provides a ``QuerySet.raw()`` method, which allows +you to perform raw SQL queries on relational databases. However, {+django-odm+} +does not support the ``raw()`` method. Instead, the ODM provides the +``QuerySet.raw_aggregate()`` method, which you can use to send instructions +to the database in pipeline stages. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``Movie`` and ``Theater`` models, which +represent collections in the ``sample_mflix`` database from the :atlas:`Atlas sample datasets `. +The model classes have the following definitions: + +.. literalinclude:: /includes/interact-data/raw-queries.py + :start-after: start-models + :end-before: end-models + :language: python + :copyable: + +To learn how to create a Django application that uses a similar ``Movie`` +model to interact with MongoDB documents, visit the :ref:`django-get-started` +tutorial. + +.. _django-raw-queries-run: + +Run Raw Queries +--------------- + +To run a raw database query, pass an aggregation pipeline +to the ``QuerySet.raw_aggregate()`` method. Aggregation pipelines +contain one or more stages that provide instructions on how to +process documents. After calling the ``raw_aggregate()`` method, +{+django-odm+} passes your pipeline to the ``pymongo.collection.Collection.aggregate()`` +method and returns the query results as model objects. + +.. tip:: + + To learn more about constructing aggregation pipelines, see + :manual:`Aggregation Pipeline ` + in the {+mdb-server+} manual. + +This section shows how to use the ``raw_aggregate()`` method +to perform the following tasks: + +- :ref:`django-raw-queries-filter-group` +- :ref:`django-raw-queries-search` +- :ref:`django-raw-queries-geospatial` + +.. _django-raw-queries-filter-group: + +Filter and Project Document Fields +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This example runs a raw database query by calling the +``raw_aggregate()`` method on your ``Movie`` objects, +which represent documents in the ``sample_mflix.movies`` +collection. The code passes the following aggregation pipeline stages +to ``raw_aggregate()``: + +- ``$match``: Filters for documents that have a ``title`` + field value of ``"The Parent Trap"`` + +- ``$project``: Includes the ``title`` and ``released`` fields + of the returned model objects + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/raw-queries.py + :start-after: start-filter-project + :end-before: end-filter-project + :language: python + + .. output:: + :language: none + :visible: false + + Plot of The Parent Trap, released on 1961-06-21 00:00:00+00:00: + Teenage twin girls swap places and scheme to reunite their divorced parents. + + Plot of The Parent Trap, released on 1998-07-29 00:00:00+00:00: + Identical twins, separated at birth and each raised by one of their + biological parents, discover each other for the first time at summer + camp and make a plan to bring their wayward parents back together. + +.. note:: + + The ``raw_aggregate()`` method returns deferred model instances, + which means that you can load fields omitted by the ``$project`` stage + on demand. In the preceding example, the query retrieves the ``title`` + and ``released`` fields. The print statement runs a separate query + to retrieve the ``plot`` field. + +.. _django-raw-queries-search: + +Run an Atlas Search Query +~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can run Atlas Search queries on your database to perform +fine-grained text searches. These queries provide advanced search +functionality, such as matching text phrases, scoring results for +relevance, and highlighting matches. + +To specify an Atlas Search query, create an Atlas Search index +that covers the fields you want to query. Then, pass a ``$search`` +or ``$searchMeta`` stage in an aggregation pipeline parameter to +the ``raw_aggregate()`` method. + +.. important:: + + You cannot use {+django-odm+} to create Atlas Search indexes. + + For instructions on using the PyMongo driver to create an Atlas + Search index, see `Atlas Search and Vector Search Indexes + `__ + in the PyMongo documentation. + + For instructions on alternative methods of creating search indexes, + see :atlas:`Create an Atlas Search Index ` + in the Atlas documentation. + +This example runs an Atlas Search query by passing the ``$search`` pipeline +stage to the ``raw_aggregate()`` method. The code performs the following +actions: + +- Specifies the Atlas Search index that covers the ``plot`` field +- Queries for documents whose ``plot`` values contain the string + ``"whirlwind romance"`` with no more than ``3`` words between them +- Returns portions of the ``plot`` string values that match + the query and metadata that indicates where the matches + occurred +- Includes the ``title`` field and the ``highlight``, or matching text, + of each result + +.. io-code-block:: + :copyable: true + + .. input:: /includes/interact-data/raw-queries.py + :start-after: start-atlas-search + :end-before: end-atlas-search + :language: python + + .. output:: + :language: none + :visible: false + + Title: Tokyo Fiancèe, text match details: [{'score': 2.3079638481140137, 'path': 'plot', + 'texts': [{'value': 'A young Japanophile Belgian woman in Tokyo falls into a ', 'type': 'text'}, + {'value': 'whirlwind', 'type': 'hit'}, {'value': ' ', 'type': 'text'}, {'value': 'romance', + 'type': 'hit'}, {'value': ' with a Francophile Japanese student.', 'type': 'text'}]}] + + Title: Designing Woman, text match details: [{'score': 2.3041324615478516, 'path': 'plot', + 'texts': [{'value': 'A sportswriter and a fashion-designer marry after a ', 'type': 'text'}, + {'value': 'whirlwind', 'type': 'hit'}, {'value': ' ', 'type': 'text'}, {'value': 'romance', + 'type': 'hit'}, {'value': ', and discover they have little in common.', 'type': 'text'}]}] + + Title: Vivacious Lady, text match details: [{'score': 2.220963478088379, 'path': 'plot', + 'texts': [{'value': 'On a quick trip to the city, young university professor Peter Morgan + falls in love with nightclub performer Francey Brent and marries her after a ', 'type': 'text'}, + {'value': 'whirlwind', 'type': 'hit'}, {'value': ' ', 'type': 'text'}, {'value': 'romance', + 'type': 'hit'}, {'value': '. ', 'type': 'text'}]}] + + Title: Ek Hasina Thi, text match details: [{'score': 3.11773419380188, 'path': 'plot', 'texts': + [{'value': 'The ', 'type': 'text'}, {'value': 'whirlwind', 'type': 'hit'}, {'value': ' ', 'type': + 'text'}, {'value': 'romance', 'type': 'hit'}, {'value': ' turns sour when she is framed for his + underworld crimes. ', 'type': 'text'}]}] + + Title: Kick, text match details: [{'score': 2.00649356842041, 'path': 'plot', 'texts': [{'value': + 'An adrenaline junkie walks away from a ', 'type': 'text'}, {'value': 'whirlwind', 'type': 'hit'}, + {'value': ' ', 'type': 'text'}, {'value': 'romance', 'type': 'hit'}, {'value': ' and embraces a new + life as a thief, though he soon finds himself pursued by veteran police officer and engaged in a turf + war with a local gangster.', 'type': 'text'}]}] + + Title: A Tale of Winter, text match details: [{'score': 3.3978850841522217, 'path': 'plot', 'texts': + [{'value': 'Felicie and Charles have a serious if ', 'type': 'text'}, {'value': 'whirlwind', 'type': + 'hit'}, {'value': ' holiday ', 'type': 'text'}, {'value': 'romance', 'type': 'hit'}, {'value': '. ', + 'type': 'text'}]}] + +.. important:: + + When running the preceding example, ensure that you replace + the ```` placeholder with the name of your + Atlas Search index that covers the ``plot`` field. + +.. _django-raw-queries-geospatial: + +Query Geospatial Data +~~~~~~~~~~~~~~~~~~~~~ + +You can use the ``raw_aggregate()`` method to run queries +on fields containing geospatial data. Geospatial data represents +a geographic location on the surface of the Earth or on a +Euclidean plane. + +To run a geospatial query, create a ``2d`` or ``2dsphere`` index on fields +containing geospatial data. Then, pass one of the following +query operators in an aggregation pipeline parameter to +the ``raw_aggregate()`` method: + +- ``$near`` +- ``$geoWithin`` +- ``$nearSphere`` +- ``$geoIntersects`` + +.. important:: + + You cannot use {+django-odm+} to create ``2d`` or ``2dsphere`` indexes. + + For instructions on using the PyMongo driver to create geospatial + indexes, see `Geospatial Indexes + `__ + in the PyMongo documentation. + + For instructions on using the MongoDB Shell to create geospatial + indexes, see :manual:`Geospatial Indexes ` + in the {+mdb-server+} manual. + +This example runs a geospatial query by passing the ``$match`` and +``$geoWithin`` pipeline stages to the ``raw_aggregate()`` method. The +code performs the following actions: + +- Specifies a list of coordinates that represent Chicago's boundaries +- Queries for documents in which the ``location.geo`` field stores a + location within the Chicago area +- Retrieves and prints the ``theaterId`` values of each movie theater in Chicago + +.. io-code-block:: + :copyable: true + + .. input:: /includes/interact-data/raw-queries.py + :start-after: start-geo + :end-before: end-geo + :language: python + + .. output:: + :language: none + :visible: false + + Theater ID: 2447 + Theater ID: 311 + Theater ID: 320 + Theater ID: 2960 + Theater ID: 2741 + Theater ID: 306 + Theater ID: 322 + Theater ID: 319 + Theater ID: 2862 + Theater ID: 1777 + Theater ID: 814 + Theater ID: 323 + +Additional Information +---------------------- + +To view more examples that use the ``raw_aggregate()`` method, +see `QuerySet API Reference <{+django-api+}querysets.html>`__ +in the {+django-odm+} API documentation. + +To learn more about running aggregation operations, see +:manual:`Aggregation Operations ` +in the {+mdb-server+} manual. + +To learn more about Atlas Search, see :atlas:`Atlas Search ` +in the Atlas documentation. + +To learn more about running geospatial queries, see +:manual:`Geospatial Queries ` +in the {+mdb-server+} manual. \ No newline at end of file From dcfb881d55b17fc142fb551e9a83544eabf032e9 Mon Sep 17 00:00:00 2001 From: norareidy Date: Tue, 14 Jan 2025 14:23:04 -0500 Subject: [PATCH 02/14] landing --- source/index.txt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/source/index.txt b/source/index.txt index 2e57793..534910f 100644 --- a/source/index.txt +++ b/source/index.txt @@ -2,9 +2,22 @@ Django MongoDB Backend ====================== -.. default-domain:: mongodb +.. facet:: + :name: programming_language + :values: python -Your words here. Don't forget to add a toctree! +.. meta:: + :keywords: home -Have a lovely day! +.. toctree:: + Interact with Data + +Welcome to the documentation site for the official {+django-odm+}, +a Django database backend that uses PyMongo to connect to MongoDB. + +Interact with Data +------------------ + +Learn how to use {+ddjango-odm+} to perform operations on MongoDB data +in the :ref:`django-interact-data` section. \ No newline at end of file From 2fcca1a7a91bb244d8de266bdb870d1df12ac1ac Mon Sep 17 00:00:00 2001 From: norareidy Date: Tue, 14 Jan 2025 14:28:54 -0500 Subject: [PATCH 03/14] code edits --- source/includes/interact-data/raw-queries.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/includes/interact-data/raw-queries.py b/source/includes/interact-data/raw-queries.py index f965a37..ad0f687 100644 --- a/source/includes/interact-data/raw-queries.py +++ b/source/includes/interact-data/raw-queries.py @@ -1,19 +1,19 @@ # start-models from django.db import models -from django_mongodb_backend.fields import EmbeddedModelField, ArrayField +from django_mongodb_backend.fields import ArrayField from django_mongodb_backend.managers import MongoManager class Movie(models.Model): title = models.CharField(max_length=200) - plot = models.TextField(null=True) + plot = models.TextField(blank=True) runtime = models.IntegerField(default=0) - released = models.DateTimeField("release date", null=True) - awards = EmbeddedModelField(Award) - genres = ArrayField(models.CharField(max_length=100), blank=True) + released = models.DateTimeField("release date", null=True, blank=True) + genres = ArrayField(models.CharField(max_length=100), null=True, blank=True) objects = MongoManager() class Meta: db_table = "movies" + managed = False def __str__(self): return self.title @@ -24,6 +24,7 @@ class Theater(models.Model): class Meta: db_table = "theaters" + managed = False def __str__(self): return self.title From 39ba0a550c51ae5d0af49308e5f50396417722f7 Mon Sep 17 00:00:00 2001 From: norareidy Date: Thu, 16 Jan 2025 12:25:23 -0500 Subject: [PATCH 04/14] jib feedback --- source/interact-data/raw-queries.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source/interact-data/raw-queries.txt b/source/interact-data/raw-queries.txt index 790c7be..ce63b2a 100644 --- a/source/interact-data/raw-queries.txt +++ b/source/interact-data/raw-queries.txt @@ -25,12 +25,20 @@ raw queries on your MongoDB database. Raw queries allow you to query the database by using MongoDB's aggregation pipeline syntax rather than Django methods. -The Django QuerySet API provides a ``QuerySet.raw()`` method, which allows +The Django ``QuerySet`` API provides a ``QuerySet.raw()`` method, which allows you to perform raw SQL queries on relational databases. However, {+django-odm+} does not support the ``raw()`` method. Instead, the ODM provides the ``QuerySet.raw_aggregate()`` method, which you can use to send instructions to the database in pipeline stages. +.. note:: + + Django provides a ``QuerySet.aggregate()`` method, which differs from the + ``QuerySet.raw_aggregate()`` method. You can use ``aggregate()`` to retrieve + values by aggregating a collection of model objects. To learn more about + the ``aggregate()`` method, see `Aggregation <{+django-docs+}/topics/db/aggregation/>`__ + in the Django documentation. + Sample Data ~~~~~~~~~~~ From 06cef820cd76e24f07ceff3eebfb8c01feedd8ff Mon Sep 17 00:00:00 2001 From: norareidy Date: Fri, 17 Jan 2025 11:35:59 -0500 Subject: [PATCH 05/14] managers --- source/interact-data/raw-queries.txt | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/source/interact-data/raw-queries.txt b/source/interact-data/raw-queries.txt index fdaf9a3..75df539 100644 --- a/source/interact-data/raw-queries.txt +++ b/source/interact-data/raw-queries.txt @@ -25,10 +25,10 @@ raw queries on your MongoDB database. Raw queries allow you to query the database by using MongoDB's aggregation pipeline syntax rather than Django methods. -The Django ``QuerySet`` API provides a ``QuerySet.raw()`` method, which allows +The Django ``QuerySet`` API provides a ``raw()`` method, which allows you to perform raw SQL queries on relational databases. However, {+django-odm+} does not support the ``raw()`` method. Instead, the ODM provides the -``QuerySet.raw_aggregate()`` method, which you can use to send instructions +``raw_aggregate()`` method, which you can use to send instructions to the database in pipeline stages. .. note:: @@ -39,12 +39,22 @@ to the database in pipeline stages. the ``aggregate()`` method, see `Aggregation <{+django-docs+}/topics/db/aggregation/>`__ in the Django documentation. +You can run database queries by calling ``QuerySet`` methods on your model's +``Manager``. The ``Manager`` class handles database operations and allows you +to interact with your MongoDB data by referencing Django models. By default, +Django adds a ``Manager`` named ``objects`` to every model class. This default +``Manager`` does not support the ``raw_aggregate()`` method. To use this +MongoDB-specific method, set your model's ``objects`` field to a custom +manager called ``MongoManager``. + Sample Data ~~~~~~~~~~~ The examples in this guide use the ``Movie`` and ``Theater`` models, which represent collections in the ``sample_mflix`` database from the :atlas:`Atlas sample datasets `. -The model classes have the following definitions: +The ``Movie`` model explicitly sets the ``objects`` field to use a custom ``MongoManager``, +rather than Django's default ``Manager`` class. The model classes have the following +definitions: .. literalinclude:: /includes/interact-data/raw-queries.py :start-after: start-models @@ -62,7 +72,7 @@ Run Raw Queries --------------- To run a raw database query, pass an aggregation pipeline -to the ``QuerySet.raw_aggregate()`` method. Aggregation pipelines +to the ``raw_aggregate()`` method. Aggregation pipelines contain one or more stages that provide instructions on how to process documents. After calling the ``raw_aggregate()`` method, {+django-odm+} passes your pipeline to the ``pymongo.collection.Collection.aggregate()`` @@ -87,10 +97,9 @@ Filter and Project Document Fields ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This example runs a raw database query by calling the -``raw_aggregate()`` method on your ``Movie`` objects, -which represent documents in the ``sample_mflix.movies`` -collection. The code passes the following aggregation pipeline stages -to ``raw_aggregate()``: +``raw_aggregate()`` method on your ``Movie`` model's ``MongoManager``, +which queries the ``sample_mflix.movies`` collection. The code +passes the following aggregation pipeline stages to ``raw_aggregate()``: - ``$match``: Filters for documents that have a ``title`` field value of ``"The Parent Trap"`` From 257eb8559f847f7d4352e733632653aa86a76454 Mon Sep 17 00:00:00 2001 From: norareidy Date: Fri, 17 Jan 2025 11:37:55 -0500 Subject: [PATCH 06/14] fix --- source/interact-data/raw-queries.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/interact-data/raw-queries.txt b/source/interact-data/raw-queries.txt index 75df539..2722aac 100644 --- a/source/interact-data/raw-queries.txt +++ b/source/interact-data/raw-queries.txt @@ -52,7 +52,7 @@ Sample Data The examples in this guide use the ``Movie`` and ``Theater`` models, which represent collections in the ``sample_mflix`` database from the :atlas:`Atlas sample datasets `. -The ``Movie`` model explicitly sets the ``objects`` field to use a custom ``MongoManager``, +These models explicitly set the ``objects`` field to use a custom ``MongoManager``, rather than Django's default ``Manager`` class. The model classes have the following definitions: From 147c936068937a2310cde4d24aa55fc7ef0fc10f Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 22 Jan 2025 13:43:54 -0500 Subject: [PATCH 07/14] mongoclient operations --- snooty.toml | 1 + source/interact-data/raw-queries.txt | 30 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/snooty.toml b/snooty.toml index c42083e..dbd8c3c 100644 --- a/snooty.toml +++ b/snooty.toml @@ -15,3 +15,4 @@ api = "https://django-mongodb.readthedocs.io/en/latest/" mdb-server = "MongoDB Server" django-version = "5.0" django-docs = "https://docs.djangoproject.com/en/{+django-version+}" +pymongo-docs = "https://www.mongodb.com/docs/languages/python/pymongo-driver/current/" diff --git a/source/interact-data/raw-queries.txt b/source/interact-data/raw-queries.txt index 2722aac..760db0b 100644 --- a/source/interact-data/raw-queries.txt +++ b/source/interact-data/raw-queries.txt @@ -47,6 +47,9 @@ Django adds a ``Manager`` named ``objects`` to every model class. This default MongoDB-specific method, set your model's ``objects`` field to a custom manager called ``MongoManager``. +As an alternative to the ``raw_aggregate()`` method, you can run queries directly +on your ``MongoClient`` object for expanded access to your MongoDB data. + Sample Data ~~~~~~~~~~~ @@ -293,6 +296,33 @@ code performs the following actions: Theater ID: 814 Theater ID: 323 +.. _django-client-operations: + +MongoClient Operations +---------------------- + +If you want to run database operations that neither the ``QuerySet`` API +nor the ``raw_aggregate()`` method provide, you can operate on your +``MongoClient`` directly. When working with the ``MongoClient``, you can +can access the PyMongo driver's database operations. Use the following +syntax to expose the ``MongoClient``: + +.. code-block:: + :language: python + + from django.db import connections + + client = connections[""].database.client + +Replace the ``""`` placeholder with the key in your +``DATABASES`` dictionary that corresponds to your target database. To +use your default database, replace the placeholder with ``"default"``. + +.. tip:: + + To learn how to use PyMongo to interact with MongoDB data, + see the `PyMongo documentation. <{+pymongo-docs+}>`__ + Additional Information ---------------------- From d9c324b73c4d5bf8d53a931419a28864d64df6f4 Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 22 Jan 2025 15:23:49 -0500 Subject: [PATCH 08/14] more mongoclient --- snooty.toml | 2 +- source/interact-data/raw-queries.txt | 27 ++++++++++++++------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/snooty.toml b/snooty.toml index dbd8c3c..23aa577 100644 --- a/snooty.toml +++ b/snooty.toml @@ -15,4 +15,4 @@ api = "https://django-mongodb.readthedocs.io/en/latest/" mdb-server = "MongoDB Server" django-version = "5.0" django-docs = "https://docs.djangoproject.com/en/{+django-version+}" -pymongo-docs = "https://www.mongodb.com/docs/languages/python/pymongo-driver/current/" +pymongo-docs = "https://www.mongodb.com/docs/languages/python/pymongo-driver/current" diff --git a/source/interact-data/raw-queries.txt b/source/interact-data/raw-queries.txt index 760db0b..a490cd2 100644 --- a/source/interact-data/raw-queries.txt +++ b/source/interact-data/raw-queries.txt @@ -155,16 +155,17 @@ the ``raw_aggregate()`` method. .. important:: - You cannot use {+django-odm+} to create Atlas Search indexes. + You cannot use the ``QuerySet`` API to create Atlas Search indexes. + However, you can create an index by exposing your ``MongoClient`` + object directly, on which you can call the PyMongo driver's + ``create_search_index()`` method. To learn how to expose the + ``MongoClient``, see the :ref:`django-client-operations` section + of this guide. For instructions on using the PyMongo driver to create an Atlas Search index, see `Atlas Search and Vector Search Indexes - `__ + <{+pymongo-docs+}/indexes/atlas-search-index/>`__ in the PyMongo documentation. - - For instructions on alternative methods of creating search indexes, - see :atlas:`Create an Atlas Search Index ` - in the Atlas documentation. This example runs an Atlas Search query by passing the ``$search`` pipeline stage to the ``raw_aggregate()`` method. The code performs the following @@ -251,16 +252,16 @@ the ``raw_aggregate()`` method: .. important:: - You cannot use {+django-odm+} to create ``2d`` or ``2dsphere`` indexes. + You cannot use the ``QuerySet`` API to create ``2d`` or ``2dsphere`` indexes. + However, you can create indexes by exposing your ``MongoClient`` + object directly, on which you can call the PyMongo driver's + ``create_index()`` method. To learn how to expose the + ``MongoClient``, see the :ref:`django-client-operations` section + of this guide. For instructions on using the PyMongo driver to create geospatial - indexes, see `Geospatial Indexes - `__ + indexes, see `Geospatial Indexes <{+pymongo-docs+}/indexes/geospatial-index/>`__ in the PyMongo documentation. - - For instructions on using the MongoDB Shell to create geospatial - indexes, see :manual:`Geospatial Indexes ` - in the {+mdb-server+} manual. This example runs a geospatial query by passing the ``$match`` and ``$geoWithin`` pipeline stages to the ``raw_aggregate()`` method. The From 33adb284c883f3cd4f36f11a498ef365dc333147 Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 22 Jan 2025 18:00:55 -0500 Subject: [PATCH 09/14] fix code --- source/interact-data/raw-queries.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/interact-data/raw-queries.txt b/source/interact-data/raw-queries.txt index a490cd2..e87e176 100644 --- a/source/interact-data/raw-queries.txt +++ b/source/interact-data/raw-queries.txt @@ -308,8 +308,7 @@ nor the ``raw_aggregate()`` method provide, you can operate on your can access the PyMongo driver's database operations. Use the following syntax to expose the ``MongoClient``: -.. code-block:: - :language: python +.. code-block:: python from django.db import connections From 5b67a93cc6aedc782d5743afd2d791bb5dd6963c Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 22 Jan 2025 18:27:18 -0500 Subject: [PATCH 10/14] use include --- source/includes/interact-data/raw-queries.py | 2 -- source/includes/use-sample-data.rst | 23 ++++++++++++++++++++ source/interact-data/raw-queries.txt | 16 +++++++++++--- 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 source/includes/use-sample-data.rst diff --git a/source/includes/interact-data/raw-queries.py b/source/includes/interact-data/raw-queries.py index ad0f687..ec78a93 100644 --- a/source/includes/interact-data/raw-queries.py +++ b/source/includes/interact-data/raw-queries.py @@ -31,8 +31,6 @@ def __str__(self): # end-models # start-filter-project -from sample_mflix.models import Movie - movies = Movie.objects.raw_aggregate([ {"$match": {"title": "The Parent Trap"}}, {"$project": { diff --git a/source/includes/use-sample-data.rst b/source/includes/use-sample-data.rst new file mode 100644 index 0000000..37407be --- /dev/null +++ b/source/includes/use-sample-data.rst @@ -0,0 +1,23 @@ +The |model-classes| an inner ``Meta`` class and a ``__str__()`` method. +To learn about these model features, see :ref:`django-models-define` in the +Create Models guide. + +Run Code Examples +````````````````` + +You can use the Python interactive shell to run the code examples. +To enter the shell, run the following command from your project's +root directory: + +.. code-block:: bash + + python manage.py shell + +After entering the Python shell, ensure that you import the following models and +modules: + +|model-imports| + +To learn how to create a {+framework+} application that uses the ``Movie`` +model and the Python interactive shell to interact with MongoDB documents, +visit the :ref:`django-get-started` tutorial. \ No newline at end of file diff --git a/source/interact-data/raw-queries.txt b/source/interact-data/raw-queries.txt index e87e176..89e0468 100644 --- a/source/interact-data/raw-queries.txt +++ b/source/interact-data/raw-queries.txt @@ -65,9 +65,19 @@ definitions: :language: python :copyable: -To learn how to create a Django application that uses a similar ``Movie`` -model to interact with MongoDB documents, visit the :ref:`django-get-started` -tutorial. +.. include:: /includes/use-sample-data.rst + + .. replacement:: model-classes + + ``Movie`` and ``Theater`` models include + + .. replacement:: model-imports + + .. code-block:: python + + from .models import Movie, Theater + from {+framework+}.utils import timezone + from datetime import datetime .. _django-raw-queries-run: From a7e72509291cc38d84e87c07267440520b08c08c Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 22 Jan 2025 19:16:57 -0500 Subject: [PATCH 11/14] query api section --- source/interact-data/raw-queries.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/interact-data/raw-queries.txt b/source/interact-data/raw-queries.txt index 89e0468..dbb3d8c 100644 --- a/source/interact-data/raw-queries.txt +++ b/source/interact-data/raw-queries.txt @@ -23,7 +23,11 @@ Overview In this guide, you can learn how to use {+django-odm+} to run raw queries on your MongoDB database. Raw queries allow you to query the database by using MongoDB's aggregation pipeline syntax -rather than Django methods. +rather than Django methods. You can also run queries directly +on your ``MongoClient`` object for expanded access to your MongoDB data. + +Query API +~~~~~~~~~ The Django ``QuerySet`` API provides a ``raw()`` method, which allows you to perform raw SQL queries on relational databases. However, {+django-odm+} @@ -47,9 +51,6 @@ Django adds a ``Manager`` named ``objects`` to every model class. This default MongoDB-specific method, set your model's ``objects`` field to a custom manager called ``MongoManager``. -As an alternative to the ``raw_aggregate()`` method, you can run queries directly -on your ``MongoClient`` object for expanded access to your MongoDB data. - Sample Data ~~~~~~~~~~~ From e1219806d679a55c09a371c5fe3194baef2d3997 Mon Sep 17 00:00:00 2001 From: norareidy Date: Thu, 23 Jan 2025 10:00:25 -0500 Subject: [PATCH 12/14] fix --- source/interact-data/raw-queries.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/interact-data/raw-queries.txt b/source/interact-data/raw-queries.txt index dbb3d8c..970060c 100644 --- a/source/interact-data/raw-queries.txt +++ b/source/interact-data/raw-queries.txt @@ -77,7 +77,7 @@ definitions: .. code-block:: python from .models import Movie, Theater - from {+framework+}.utils import timezone + from django.utils import timezone from datetime import datetime .. _django-raw-queries-run: From 10f26373af1c758f992ac227c0ae742ddaff809f Mon Sep 17 00:00:00 2001 From: norareidy Date: Thu, 23 Jan 2025 14:46:03 -0500 Subject: [PATCH 13/14] sample data include edit --- source/includes/use-sample-data.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/includes/use-sample-data.rst b/source/includes/use-sample-data.rst index 37407be..15433ac 100644 --- a/source/includes/use-sample-data.rst +++ b/source/includes/use-sample-data.rst @@ -1,5 +1,7 @@ -The |model-classes| an inner ``Meta`` class and a ``__str__()`` method. -To learn about these model features, see :ref:`django-models-define` in the +The |model-classes| an inner ``Meta`` class, which specifies +model metadata, and a ``__str__()`` method, which sets the +model's string representation to its ``title`` field. To learn about +these model features, see :ref:`django-models-define` in the Create Models guide. Run Code Examples From 80ddf07bd9502782ca3031c1bd286c2524484c4a Mon Sep 17 00:00:00 2001 From: norareidy Date: Thu, 23 Jan 2025 14:49:28 -0500 Subject: [PATCH 14/14] fix str --- source/includes/interact-data/raw-queries.py | 2 +- source/includes/use-sample-data.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/includes/interact-data/raw-queries.py b/source/includes/interact-data/raw-queries.py index ec78a93..9c85d06 100644 --- a/source/includes/interact-data/raw-queries.py +++ b/source/includes/interact-data/raw-queries.py @@ -27,7 +27,7 @@ class Meta: managed = False def __str__(self): - return self.title + return self.theaterId # end-models # start-filter-project diff --git a/source/includes/use-sample-data.rst b/source/includes/use-sample-data.rst index 15433ac..c8f80cb 100644 --- a/source/includes/use-sample-data.rst +++ b/source/includes/use-sample-data.rst @@ -1,7 +1,7 @@ The |model-classes| an inner ``Meta`` class, which specifies -model metadata, and a ``__str__()`` method, which sets the -model's string representation to its ``title`` field. To learn about -these model features, see :ref:`django-models-define` in the +model metadata, and a ``__str__()`` method, which defines the +model's string representation. To learn about these +model features, see :ref:`django-models-define` in the Create Models guide. Run Code Examples