From b395963f42389dcd5e4a3871f13f454533537ec7 Mon Sep 17 00:00:00 2001 From: norareidy Date: Tue, 17 Jun 2025 15:52:56 -0400 Subject: [PATCH 1/3] DOCSP-50754: Add agg tutorials links --- snooty.toml | 1 - source/aggregation.txt | 51 +--- source/aggregation/filtered-subset.txt | 218 ----------------- source/aggregation/group-total.txt | 258 -------------------- source/aggregation/multi-field-join.txt | 302 ------------------------ source/aggregation/one-to-one-join.txt | 273 --------------------- source/aggregation/unpack-arrays.txt | 239 ------------------- 7 files changed, 6 insertions(+), 1336 deletions(-) delete mode 100644 source/aggregation/filtered-subset.txt delete mode 100644 source/aggregation/group-total.txt delete mode 100644 source/aggregation/multi-field-join.txt delete mode 100644 source/aggregation/one-to-one-join.txt delete mode 100644 source/aggregation/unpack-arrays.txt diff --git a/snooty.toml b/snooty.toml index 4078fc67..8b95c797 100644 --- a/snooty.toml +++ b/snooty.toml @@ -3,7 +3,6 @@ title = "PyMongo Driver" toc_landing_pages = [ "/get-started", "/connect", - "/aggregation", "/security", "/security/authentication", "/data-formats", diff --git a/source/aggregation.txt b/source/aggregation.txt index 7f0b6aa9..8d8e8d3a 100644 --- a/source/aggregation.txt +++ b/source/aggregation.txt @@ -18,16 +18,6 @@ Transform Your Data with Aggregation :depth: 2 :class: singlecol -.. toctree:: - :titlesonly: - :maxdepth: 1 - - Filtered Subset - Group & Total - Unpack Arrays & Group - One-to-One Join - Multi-Field Join - Overview -------- @@ -50,6 +40,12 @@ The **aggregation pipeline** is the assembly line, **aggregation stages** are th assembly stations, and **operator expressions** are the specialized tools. +.. sharedinclude:: dbx/agg-tutorials-manual-tip.rst + + .. replacement:: language + + :guilabel:`{+language+}` + Aggregation Versus Find Operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -281,41 +277,6 @@ To learn more about explaining MongoDB operations, see :manual:`Explain Output ` and :manual:`Query Plans. ` -Aggregation Tutorials -~~~~~~~~~~~~~~~~~~~~~ - -To view step-by-step explanations of common aggregation tasks, see -the following tutorials: - -- :ref:`pymongo-aggregation-filtered-subset` -- :ref:`pymongo-aggregation-group-total` -- :ref:`pymongo-aggregation-arrays` -- :ref:`pymongo-aggregation-one-to-one` -- :ref:`pymongo-aggregation-multi-field` - -Aggregation tutorials provide detailed explanations of common -aggregation tasks in a step-by-step format. The tutorials are adapted -from examples in the `Practical MongoDB Aggregations book -`__ by Paul Done. - -Each tutorial includes the following sections: - -- **Introduction**, which describes the purpose and common use cases of the - aggregation type. This section also describes the example and desired - outcome that the tutorial demonstrates. - -- **Before You Get Started**, which describes the necessary databases, - collections, and sample data that you must have before building the - aggregation pipeline and performing the aggregation. - -- **Tutorial**, which describes how to build and run the aggregation - pipeline. This section describes each stage of the completed - aggregation tutorial, and then explains how to run and interpret the - output of the aggregation. - -At the end of each aggregation tutorial, you can find a link to a fully -runnable Python code file that you can run in your environment. - API Documentation ~~~~~~~~~~~~~~~~~ diff --git a/source/aggregation/filtered-subset.txt b/source/aggregation/filtered-subset.txt deleted file mode 100644 index 8f59a273..00000000 --- a/source/aggregation/filtered-subset.txt +++ /dev/null @@ -1,218 +0,0 @@ -.. _pymongo-aggregation-filtered-subset: - -=============== -Filtered Subset -=============== - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -.. facet:: - :name: genre - :values: tutorial - -.. meta:: - :keywords: code example, python, sort, limit, aggregation - -Introduction ------------- - -In this tutorial, you can learn how to use {+driver-short+} to -construct an aggregation pipeline, perform the -aggregation on a collection, and print the results by completing and -running a sample app. This aggregation performs the following operations: - -- Matches a subset of documents by a field value -- Formats result documents - -Aggregation Task Summary -~~~~~~~~~~~~~~~~~~~~~~~~ - -This tutorial demonstrates how to query a collection for a specific -subset of documents in a collection. The results contain -documents that describe the three youngest people who are engineers. - -This example uses one collection, ``persons``, which contains -documents describing people. Each document includes a person's name, -date of birth, vocation, and other details. - -Before You Get Started ----------------------- - -.. include:: /includes/aggregation-tutorial-intro.rst - -After you set up the app, access the ``persons`` collection by adding the -following code to the application: - -.. literalinclude:: /includes/aggregation/filtered-subset.py - :language: python - :copyable: true - :start-after: start-collection - :end-before: end-collection - :dedent: - -Delete any existing data in the collections and insert sample data into -the ``persons`` collection as shown in the following code. Select the -:guilabel:`Synchronous` or :guilabel:`Asynchronous` tab to see the corresponding code: - -.. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/filtered-subset.py - :language: python - :copyable: true - :start-after: start-insert-persons - :end-before: end-insert-persons - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/filtered-subset-async.py - :language: python - :copyable: true - :start-after: start-insert-persons - :end-before: end-insert-persons - :dedent: - -Tutorial --------- - -.. procedure:: - :style: connected - - .. step:: Add a match stage for people who are engineers - - First, add a :manual:`$match - ` stage that finds documents in which - the value of the ``vocation`` field is ``"ENGINEER"``: - - .. literalinclude:: /includes/aggregation/filtered-subset.py - :language: python - :copyable: true - :start-after: start-match - :end-before: end-match - :dedent: - - .. step:: Add a sort stage to sort from youngest to oldest - - Next, add a :manual:`$sort - ` stage that sorts the - documents in descending order by the ``dateofbirth`` field to - list the youngest people first: - - .. literalinclude:: /includes/aggregation/filtered-subset.py - :language: python - :copyable: true - :start-after: start-sort - :end-before: end-sort - :dedent: - - .. step:: Add a limit stage to see only three results - - Next, add a :manual:`$limit ` - stage to the pipeline to output only the first three documents in - the results. - - .. literalinclude:: /includes/aggregation/filtered-subset.py - :language: python - :copyable: true - :start-after: start-limit - :end-before: end-limit - :dedent: - - .. step:: Add an unset stage to remove unneeded fields - - Finally, add an :manual:`$unset - ` stage. The - ``$unset`` stage removes unnecessary fields from the result documents: - - .. literalinclude:: /includes/aggregation/filtered-subset.py - :language: python - :copyable: true - :start-after: start-unset - :end-before: end-unset - :dedent: - - .. tip:: - - Use the ``$unset`` operator instead of ``$project`` to avoid - modifying the aggregation pipeline if documents with - different fields are added to the collection. - - .. step:: Run the aggregation pipeline - - Add the following code to the end of your application to perform - the aggregation on the ``persons`` collection. Select the :guilabel:`Synchronous` or - :guilabel:`Asynchronous` tab to see the corresponding code: - - .. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/filtered-subset.py - :language: python - :copyable: true - :start-after: start-run-agg - :end-before: end-run-agg - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/filtered-subset-async.py - :language: python - :copyable: true - :start-after: start-run-agg - :end-before: end-run-agg - :dedent: - - Finally, run the following command in your shell to start your - application: - - .. code-block:: bash - - python3 agg_tutorial.py - - .. step:: Interpret results - - The aggregated result contains three documents. The documents - represent the three youngest people with the vocation of ``"ENGINEER"``, - ordered from youngest to oldest. The results omit the ``_id`` and ``address`` - fields. - - .. code-block:: javascript - :copyable: false - - { - 'person_id': '7363626383', - 'firstname': 'Carl', - 'lastname': 'Simmons', - 'dateofbirth': datetime.datetime(1998, 12, 26, 13, 13, 55), - 'vocation': 'ENGINEER' - } - { - 'person_id': '1723338115', - 'firstname': 'Olive', - 'lastname': 'Ranieri', - 'dateofbirth': datetime.datetime(1985, 5, 12, 23, 14, 30), - 'gender': 'FEMALE', - 'vocation': 'ENGINEER' - } - { - 'person_id': '6392529400', - 'firstname': 'Elise', - 'lastname': 'Smith', - 'dateofbirth': datetime.datetime(1972, 1, 13, 9, 32, 7), - 'vocation': 'ENGINEER' - } - -To view the complete code for this tutorial, see the `Completed Filtered Subset App -`__ -on GitHub. \ No newline at end of file diff --git a/source/aggregation/group-total.txt b/source/aggregation/group-total.txt deleted file mode 100644 index 42f58640..00000000 --- a/source/aggregation/group-total.txt +++ /dev/null @@ -1,258 +0,0 @@ -.. _pymongo-aggregation-group-total: - -=============== -Group and Total -=============== - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -.. facet:: - :name: genre - :values: tutorial - -.. meta:: - :keywords: code example, python, analyze, aggregation - -Introduction ------------- - -In this tutorial, you can learn how to use {+driver-short+} to -construct an aggregation pipeline, perform the -aggregation on a collection, and print the results by completing and -running a sample app. This aggregation performs the following operations: - -- Matches a subset of documents by a field value -- Groups documents by common field values -- Adds computed fields to each result document - -Aggregation Task Summary -~~~~~~~~~~~~~~~~~~~~~~~~ - -This tutorial demonstrates how to group and analyze customer order data. The -results show the list of customers who purchased items in 2020 and -includes each customer's order history for 2020. - -This example uses one collection, ``orders``, which contains documents -describing individual product orders. Since each order can correspond to -only one customer, the order documents are grouped by the -``customer_id`` field, which contains customer email addresses. - -Before You Get Started ----------------------- - -.. include:: /includes/aggregation-tutorial-intro.rst - -After you set up the app, access the ``orders`` collection by adding the -following code to the application: - -.. literalinclude:: /includes/aggregation/group-total.py - :language: python - :copyable: true - :start-after: start-coll - :end-before: end-coll - :dedent: - -Delete any existing data and insert sample data into -the ``orders`` collection as shown in the following code. Select the :guilabel:`Synchronous` -or :guilabel:`Asynchronous` tab to see the corresponding code: - -.. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/group-total.py - :language: python - :copyable: true - :start-after: start-insert-orders - :end-before: end-insert-orders - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/group-total-async.py - :language: python - :copyable: true - :start-after: start-insert-orders - :end-before: end-insert-orders - :dedent: - -Tutorial --------- - -.. procedure:: - :style: connected - - .. step:: Add a match stage for orders in 2020 - - First, add a :manual:`$match - ` stage that matches - orders placed in 2020: - - .. literalinclude:: /includes/aggregation/group-total.py - :language: python - :copyable: true - :start-after: start-match - :end-before: end-match - :dedent: - - .. step:: Add a sort stage to sort by order date - - Next, add a :manual:`$sort - ` stage to set an - ascending sort on the ``orderdate`` field to surface the earliest - 2020 purchase for each customer in the next stage: - - .. literalinclude:: /includes/aggregation/group-total.py - :language: python - :copyable: true - :start-after: start-sort1 - :end-before: end-sort1 - :dedent: - - .. step:: Add a group stage to group by email address - - Add a :manual:`$group - ` stage to group - orders by the value of the ``customer_id`` field. In this - stage, add aggregation operations that create the - following fields in the result documents: - - - ``first_purchase_date``: the date of the customer's first purchase - - ``total_value``: the total value of all the customer's purchases - - ``total_orders``: the total number of the customer's purchases - - ``orders``: the list of all the customer's purchases, - including the date and value of each purchase - - .. literalinclude:: /includes/aggregation/group-total.py - :language: python - :copyable: true - :start-after: start-group - :end-before: end-group - :dedent: - - .. step:: Add a sort stage to sort by first order date - - Next, add another :manual:`$sort - ` stage to set an - ascending sort on the ``first_purchase_date`` field: - - .. literalinclude:: /includes/aggregation/group-total.py - :language: python - :copyable: true - :start-after: start-sort2 - :end-before: end-sort2 - :dedent: - - .. step:: Add a set stage to display the email address - - Add a :manual:`$set - ` stage to recreate the - ``customer_id`` field from the values in the ``_id`` field - that were set during the ``$group`` stage: - - .. literalinclude:: /includes/aggregation/group-total.py - :language: python - :copyable: true - :start-after: start-set - :end-before: end-set - :dedent: - - .. step:: Add an unset stage to remove unneeded fields - - Finally, add an :manual:`$unset - ` stage. The - ``$unset`` stage removes the ``_id`` field from the result - documents: - - .. literalinclude:: /includes/aggregation/group-total.py - :language: python - :copyable: true - :start-after: start-unset - :end-before: end-unset - :dedent: - - .. step:: Run the aggregation pipeline - - Add the following code to the end of your application to perform - the aggregation on the ``orders`` collection. Select the :guilabel:`Synchronous` - or :guilabel:`Asynchronous` tab to see the corresponding code: - - .. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/group-total.py - :language: python - :copyable: true - :start-after: start-run-agg - :end-before: end-run-agg - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/group-total-async.py - :language: python - :copyable: true - :start-after: start-run-agg - :end-before: end-run-agg - :dedent: - - Finally, run the following command in your shell to start your - application: - - .. code-block:: bash - - python3 agg_tutorial.py - - .. step:: Interpret results - - The aggregation returns the following summary of customers' orders - from 2020: - - .. code-block:: javascript - :copyable: false - - { - 'first_purchase_date': datetime.datetime(2020, 1, 1, 8, 25, 37), - 'total_value': 63, - 'total_orders': 1, - 'orders': [ { 'orderdate': datetime.datetime(2020, 1, 1, 8, 25, 37), 'value': 63 } ], - 'customer_id': 'oranieri@warmmail.com' - } - { - 'first_purchase_date': datetime.datetime(2020, 1, 13, 9, 32, 7), - 'total_value': 436, - 'total_orders': 4, - 'orders': [ - { 'orderdate': datetime.datetime(2020, 1, 13, 9, 32, 7), 'value': 99 }, - { 'orderdate': datetime.datetime(2020, 5, 30, 8, 35, 52), 'value': 231 }, - { 'orderdate': datetime.datetime(2020, 10, 3, 13, 49, 44), 'value': 102 }, - { 'orderdate': datetime.datetime(2020, 12, 26, 8, 55, 46), 'value': 4 } - ], - 'customer_id': 'elise_smith@myemail.com' - } - { - 'first_purchase_date': datetime.datetime(2020, 8, 18, 23, 4, 48), - 'total_value': 191, - 'total_orders': 2, - 'orders': [ - { 'orderdate': datetime.datetime(2020, 8, 18, 23, 4, 48), 'value': 4 }, - { 'orderdate': datetime.datetime(2020, 11, 23, 22, 56, 53), 'value': 187 } - ], - 'customer_id': 'tj@wheresmyemail.com' - } - - The result documents contain details from all the orders from - a given customer, grouped by the customer's email address. - -To view the complete code for this tutorial, see the `Completed Group and Total App -`__ -on GitHub. diff --git a/source/aggregation/multi-field-join.txt b/source/aggregation/multi-field-join.txt deleted file mode 100644 index 3d805851..00000000 --- a/source/aggregation/multi-field-join.txt +++ /dev/null @@ -1,302 +0,0 @@ -.. _pymongo-aggregation-multi-field: - -================ -Multi-Field Join -================ - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -.. facet:: - :name: genre - :values: tutorial - -.. meta:: - :keywords: code example, python, lookup, aggregation - -Introduction ------------- - -In this tutorial, you can learn how to use {+driver-short+} to -construct an aggregation pipeline, perform the -aggregation on a collection, and print the results by completing and -running a sample app. - -This aggregation performs a multi-field join. A multi-field join occurs when there are -multiple corresponding fields in the documents of two collections that you use to -match documents together. The aggregation matches these documents on the -field values and combines information from both into one document. - -.. tip:: One-to-many Joins - - A one-to-many join is a variety of a multi-field join. When you - perform a one-to-many join, you select one field from a document that - matches a field value in multiple documents on the other side of the - join. To learn more about these data relationships, - see the Wikipedia entries about :wikipedia:`One-to-many (data model) - ` and - :wikipedia:`Many-to-many (data model) - `. - -Aggregation Task Summary -~~~~~~~~~~~~~~~~~~~~~~~~ - -This tutorial demonstrates how to combine data from a collection that -describes product information with another collection that describes -customer orders. The results show a list of products ordered in 2020 -that also contains details about each order. - -This example uses two collections: - -- ``products``, which contains documents describing the products that - a shop sells -- ``orders``, which contains documents describing individual orders - for products in a shop - -An order can only contain one product, so the aggregation uses a -multi-field join to match a product document to documents representing orders of -that product. The collections are joined by the ``name`` and -``variation`` fields in documents in the ``products`` collection, corresponding -to the ``product_name`` and ``product_variation`` fields in documents in -the ``orders`` collection. - -Before You Get Started ----------------------- - -.. include:: /includes/aggregation-tutorial-intro.rst - -After you set up the app, access the ``products`` and ``orders`` -collections by adding the following code to the application: - -.. literalinclude:: /includes/aggregation/multi-field-join.py - :language: python - :copyable: true - :start-after: start-colls - :end-before: end-colls - :dedent: - -Delete any existing data and insert sample data into -the ``products`` collection as shown in the following code. Select the :guilabel:`Synchronous` -or :guilabel:`Asynchronous` tab to see the corresponding code: - -.. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/multi-field-join.py - :language: python - :copyable: true - :start-after: start-insert-products - :end-before: end-insert-products - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/multi-field-join-async.py - :language: python - :copyable: true - :start-after: start-insert-products - :end-before: end-insert-products - :dedent: - -Delete any existing data and insert sample data into -the ``orders`` collection as shown in the following code: - -.. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/multi-field-join.py - :language: python - :copyable: true - :start-after: start-insert-orders - :end-before: end-insert-orders - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/multi-field-join-async.py - :language: python - :copyable: true - :start-after: start-insert-orders - :end-before: end-insert-orders - :dedent: - -Tutorial --------- - -.. procedure:: - :style: connected - - .. step:: Add a lookup stage to link the collections and import fields - - The first stage of the pipeline is a :manual:`$lookup - ` stage to join the - ``orders`` collection to the ``products`` collection by two - fields in each collection. The lookup stage contains an - embedded pipeline to configure the join. - - Within the embedded pipeline, add a :manual:`$match - ` stage to match the - values of two fields on each side of the join. Note that the following - code uses aliases for the ``name`` and ``variation`` fields - set when creating the ``$lookup`` stage: - - .. literalinclude:: /includes/aggregation/multi-field-join.py - :language: python - :copyable: true - :start-after: start-embedded-pl-match1 - :end-before: end-embedded-pl-match1 - :dedent: - - Within the embedded pipeline, add another :manual:`$match - ` stage to match - orders placed in 2020: - - .. literalinclude:: /includes/aggregation/multi-field-join.py - :language: python - :copyable: true - :start-after: start-embedded-pl-match2 - :end-before: end-embedded-pl-match2 - :dedent: - - Within the embedded pipeline, add an :manual:`$unset - ` stage to remove - unneeded fields from the ``orders`` collection side of the join: - - .. literalinclude:: /includes/aggregation/multi-field-join.py - :language: python - :copyable: true - :start-after: start-embedded-pl-unset - :end-before: end-embedded-pl-unset - :dedent: - - After the embedded pipeline is completed, add the - ``$lookup`` stage to the main aggregation pipeline. - Configure this stage to store the processed lookup fields in - an array field called ``orders``: - - .. literalinclude:: /includes/aggregation/multi-field-join.py - :language: python - :copyable: true - :start-after: start-lookup - :end-before: end-lookup - :dedent: - - .. step:: Add a match stage for products ordered in 2020 - - Next, add a :manual:`$match - ` stage to only show - products for which there is at least one order in 2020, - based on the ``orders`` array calculated in the previous step: - - .. literalinclude:: /includes/aggregation/multi-field-join.py - :language: python - :copyable: true - :start-after: start-match - :end-before: end-match - :dedent: - - .. step:: Add an unset stage to remove unneeded fields - - Finally, add an :manual:`$unset - ` stage. The - ``$unset`` stage removes the ``_id`` and ``description`` - fields from the result documents: - - .. literalinclude:: /includes/aggregation/multi-field-join.py - :language: python - :copyable: true - :start-after: start-unset - :end-before: end-unset - :dedent: - - .. step:: Run the aggregation pipeline - - Add the following code to the end of your application to perform - the aggregation on the ``products`` collection. Select the :guilabel:`Synchronous` - or :guilabel:`Asynchronous` tab to see the corresponding code: - - .. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/multi-field-join.py - :language: python - :copyable: true - :start-after: start-run-agg - :end-before: end-run-agg - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/multi-field-join-async.py - :language: python - :copyable: true - :start-after: start-run-agg - :end-before: end-run-agg - :dedent: - - Finally, run the following command in your shell to start your - application: - - .. code-block:: bash - - python3 agg_tutorial.py - - .. step:: Interpret results - - The aggregated result contains two documents. The documents - represent products for which there were orders placed in 2020. - Each document contains an ``orders`` array field that lists details - about each order for that product: - - .. code-block:: javascript - :copyable: false - - { - 'name': 'Asus Laptop', - 'variation': 'Standard Display', - 'category': 'ELECTRONICS', - 'orders': [ - { - 'customer_id': 'elise_smith@myemail.com', - 'orderdate': datetime.datetime(2020, 5, 30, 8, 35, 52), - 'value': 431.43 - }, - { - 'customer_id': 'jjones@tepidmail.com', - 'orderdate': datetime.datetime(2020, 12, 26, 8, 55, 46), - 'value': 429.65 - } - ] - } - { - 'name': 'Morphy Richards Food Mixer', - 'variation': 'Deluxe', - 'category': 'KITCHENWARE', - 'orders': [ - { - 'customer_id': 'oranieri@warmmail.com', - 'orderdate': datetime.datetime(2020, 1, 1, 8, 25, 37), - 'value': 63.13 - } - ] - } - - The result documents contain details from documents in the - ``orders`` collection and the ``products`` collection, joined by - the product names and variations. - -To view the complete code for this tutorial, see the `Completed Multi-field Join App -`__ -on GitHub. diff --git a/source/aggregation/one-to-one-join.txt b/source/aggregation/one-to-one-join.txt deleted file mode 100644 index 785a93b6..00000000 --- a/source/aggregation/one-to-one-join.txt +++ /dev/null @@ -1,273 +0,0 @@ -.. _pymongo-aggregation-one-to-one: - -=============== -One-to-One Join -=============== - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -.. facet:: - :name: genre - :values: tutorial - -.. meta:: - :keywords: code example, python, lookup, aggregation - -Introduction ------------- - -In this tutorial, you can learn how to use {+driver-short+} to -construct an aggregation pipeline, perform the -aggregation on a collection, and print the results by completing and -running a sample app. - -This aggregation performs a one-to-one join. A one-to-one join occurs -when a document in one collection has a field value that matches a -single document in another collection that has the same field value. The -aggregation matches these documents on the field value and combines -information from both sources into one result. - -.. tip:: - - A one-to-one join does not require the documents to have a - one-to-one relationship. To learn more about this data relationship, - see the Wikipedia entry about :wikipedia:`One-to-one (data model) - `. - -Aggregation Task Summary -~~~~~~~~~~~~~~~~~~~~~~~~ - -This tutorial demonstrates how to combine data from a collection that -describes product information with another collection that describes -customer orders. The results show a list of all orders placed in 2020 that -includes the product details associated with each order. - -This example uses two collections: - -- ``orders``: contains documents describing individual orders - for products in a shop -- ``products``: contains documents describing the products that - a shop sells - -An order can only contain one product, so the aggregation uses a -one-to-one join to match an order document to the document for the -product. The collections are joined by a field called ``product_id`` -that exists in documents in both collections. - -Before You Get Started ----------------------- - -.. include:: /includes/aggregation-tutorial-intro.rst - -After you set up the app, access the ``orders`` and ``products`` -collections by adding the following code to the application: - -.. literalinclude:: /includes/aggregation/one-to-one-join.py - :language: python - :copyable: true - :start-after: start-colls - :end-before: end-colls - :dedent: - -Delete any existing data and insert sample data into -the ``orders`` collection as shown in the following code. Select the :guilabel:`Synchronous` -or :guilabel:`Asynchronous` tab to see the corresponding code: - -.. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/one-to-one-join.py - :language: python - :copyable: true - :start-after: start-insert-orders - :end-before: end-insert-orders - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/one-to-one-join-async.py - :language: python - :copyable: true - :start-after: start-insert-orders - :end-before: end-insert-orders - :dedent: - -Delete any existing data and insert sample data into -the ``products`` collection as shown in the following code: - -.. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/one-to-one-join.py - :language: python - :copyable: true - :start-after: start-insert-products - :end-before: end-insert-products - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/one-to-one-join-async.py - :language: python - :copyable: true - :start-after: start-insert-products - :end-before: end-insert-products - :dedent: - -Tutorial --------- - -.. procedure:: - :style: connected - - .. step:: Add a match stage for orders in 2020 - - Add a :manual:`$match - ` stage that matches - orders placed in 2020: - - .. literalinclude:: /includes/aggregation/one-to-one-join.py - :language: python - :copyable: true - :start-after: start-match - :end-before: end-match - :dedent: - - .. step:: Add a lookup stage to link the collections - - Next, add a :manual:`$lookup - ` stage. The - ``$lookup`` stage joins the ``product_id`` field in the ``orders`` - collection to the ``id`` field in the ``products`` collection: - - .. literalinclude:: /includes/aggregation/one-to-one-join.py - :language: python - :copyable: true - :start-after: start-lookup - :end-before: end-lookup - :dedent: - - .. step:: Add set stages to create new document fields - - Next, add two :manual:`$set ` - stages to the pipeline. - - The first ``$set`` stage sets the ``product_mapping`` field - to the first element in the ``product_mapping`` object - created in the previous ``$lookup`` stage. - - The second ``$set`` stage creates two new fields, ``product_name`` - and ``product_category``, from the values in the - ``product_mapping`` object field: - - .. literalinclude:: /includes/aggregation/one-to-one-join.py - :language: python - :copyable: true - :start-after: start-set - :end-before: end-set - :dedent: - - .. tip:: - - Because this is a one-to-one join, the ``$lookup`` stage - adds only one array element to the input document. The pipeline - uses the :manual:`$first ` - operator to retrieve the data from this element. - - .. step:: Add an unset stage to remove unneeded fields - - Finally, add an :manual:`$unset - ` stage. The - ``$unset`` stage removes unnecessary fields from the document: - - .. literalinclude:: /includes/aggregation/one-to-one-join.py - :language: python - :copyable: true - :start-after: start-unset - :end-before: end-unset - :dedent: - - .. step:: Run the aggregation pipeline - - Add the following code to the end of your application to perform - the aggregation on the ``orders`` collection. Select the :guilabel:`Synchronous` - or :guilabel:`Asynchronous` tab to see the corresponding code: - - .. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/one-to-one-join.py - :language: python - :copyable: true - :start-after: start-run-agg - :end-before: end-run-agg - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/one-to-one-join-async.py - :language: python - :copyable: true - :start-after: start-run-agg - :end-before: end-run-agg - :dedent: - - Finally, run the following command in your shell to start your - application: - - .. code-block:: bash - - python3 agg_tutorial.py - - .. step:: Interpret results - - The aggregated result contains three documents. The documents - represent customer orders that occurred in 2020, with the - ``product_name`` and ``product_category`` of the ordered product: - - .. code-block:: javascript - :copyable: false - - { - 'customer_id': 'elise_smith@myemail.com', - 'orderdate': datetime.datetime(2020, 5, 30, 8, 35, 52), - 'value': 431.43, - 'product_name': 'Asus Laptop', - 'product_category': 'ELECTRONICS' - } - { - 'customer_id': 'oranieri@warmmail.com', - 'orderdate': datetime.datetime(2020, 1, 1, 8, 25, 37), - 'value': 63.13, - 'product_name': 'Morphy Richardds Food Mixer', - 'product_category': 'KITCHENWARE' - } - { - 'customer_id': 'jjones@tepidmail.com', - 'orderdate': datetime.datetime(2020, 12, 26, 8, 55, 46), - 'value': 429.65, - 'product_name': 'Asus Laptop', - 'product_category': 'ELECTRONICS' - } - - The result consists of documents that contain fields from - documents in the ``orders`` collection and the ``products`` - collection, joined by matching the ``product_id`` field present in - each original document. - -To view the complete code for this tutorial, see the `Completed One-to-one Join App -`__ -on GitHub. diff --git a/source/aggregation/unpack-arrays.txt b/source/aggregation/unpack-arrays.txt deleted file mode 100644 index 1feee3ed..00000000 --- a/source/aggregation/unpack-arrays.txt +++ /dev/null @@ -1,239 +0,0 @@ -.. _pymongo-aggregation-arrays: - -======================= -Unpack Arrays and Group -======================= - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -.. facet:: - :name: genre - :values: tutorial - -.. meta:: - :keywords: code example, python, analyze, array - -Introduction ------------- - -In this tutorial, you can learn how to use {+driver-short+} to -construct an aggregation pipeline, perform the -aggregation on a collection, and print the results by completing and -running a sample app. This aggregation performs the following operations: - -- Unwinds an array field into separate documents -- Matches a subset of documents by a field value -- Groups documents by common field values -- Adds computed fields to each result document - -Aggregation Task Summary -~~~~~~~~~~~~~~~~~~~~~~~~ - -This tutorial demonstrates how to create insights from customer order -data. The results show the list of products ordered that cost more than -$15, and each document contains the number of units sold and the total -sale value for each product. - -This example uses one collection, ``orders``, which contains documents -describing product orders. Since each order contains multiple products, -the first step of the aggregation is unpacking the ``products`` array -into individual product order documents. - -Before You Get Started ----------------------- - -.. include:: /includes/aggregation-tutorial-intro.rst - -After you set up the app, access the ``orders`` collection by adding the -following code to the application: - -.. literalinclude:: /includes/aggregation/unpack-arrays.py - :language: python - :copyable: true - :start-after: start-coll - :end-before: end-coll - :dedent: - -Delete any existing data and insert sample data into -the ``orders`` collection as shown in the following code. Select the :guilabel:`Synchronous` -or :guilabel:`Asynchronous` tab to see the corresponding code: - -.. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/unpack-arrays.py - :language: python - :copyable: true - :start-after: start-insert-orders - :end-before: end-insert-orders - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/unpack-arrays-async.py - :language: python - :copyable: true - :start-after: start-insert-orders - :end-before: end-insert-orders - :dedent: - -Tutorial --------- - -.. procedure:: - :style: connected - - .. step:: Add an unwind stage to unpack the array of product orders - - First, add an :manual:`$unwind - ` stage to separate the - entries in the ``products`` array into individual documents: - - .. literalinclude:: /includes/aggregation/unpack-arrays.py - :language: python - :copyable: true - :start-after: start-unwind - :end-before: end-unwind - :dedent: - - .. step:: Add a match stage for products that cost more than $15 - - Next, add a :manual:`$match - ` stage that matches - products with a ``products.price`` value greater than ``15``: - - .. literalinclude:: /includes/aggregation/unpack-arrays.py - :language: python - :copyable: true - :start-after: start-match - :end-before: end-match - :dedent: - - .. step:: Add a group stage to group by product type - - Add a :manual:`$group - ` stage to group - orders by the value of the ``prod_id`` field. In this - stage, add aggregation operations that create the - following fields in the result documents: - - - ``product``: the product name - - ``total_value``: the total value of all the sales of the product - - ``quantity``: the number of orders for the product - - .. literalinclude:: /includes/aggregation/unpack-arrays.py - :language: python - :copyable: true - :start-after: start-group - :end-before: end-group - :dedent: - - .. step:: Add a set stage to display the product ID - - Add a :manual:`$set - ` stage to recreate the - ``product_id`` field from the values in the ``_id`` field - that were set during the ``$group`` stage: - - .. literalinclude:: /includes/aggregation/unpack-arrays.py - :language: python - :copyable: true - :start-after: start-set - :end-before: end-set - :dedent: - - .. step:: Add an unset stage to remove unneeded fields - - Finally, add an :manual:`$unset - ` stage. The - ``$unset`` stage removes the ``_id`` field from the result - documents: - - .. literalinclude:: /includes/aggregation/unpack-arrays.py - :language: python - :copyable: true - :start-after: start-unset - :end-before: end-unset - :dedent: - - .. step:: Run the aggregation pipeline - - Add the following code to the end of your application to perform - the aggregation on the ``orders`` collection. Select the :guilabel:`Synchronous` - or :guilabel:`Asynchronous` tab to see the corresponding code: - - .. tabs:: - - .. tab:: Synchronous - :tabid: sync - - .. literalinclude:: /includes/aggregation/unpack-arrays.py - :language: python - :copyable: true - :start-after: start-run-agg - :end-before: end-run-agg - :dedent: - - .. tab:: Asynchronous - :tabid: async - - .. literalinclude:: /includes/aggregation/unpack-arrays-async.py - :language: python - :copyable: true - :start-after: start-run-agg - :end-before: end-run-agg - :dedent: - - Finally, run the following command in your shell to start your - application: - - .. code-block:: bash - - python3 agg_tutorial.py - - .. step:: Interpret results - - The aggregation returns the following summary of customers' orders - from 2020: - - .. code-block:: javascript - :copyable: false - - { - 'product': 'Asus Laptop', - 'total_value': 860, - 'quantity': 2, - 'product_id': 'abc12345' - } - { - 'product': 'Morphy Richards Food Mixer', - 'total_value': 431, - 'quantity': 1, - 'product_id': 'pqr88223' - } - { - 'product': 'Russell Hobbs Chrome Kettle', - 'total_value': 16, - 'quantity': 1, - 'product_id': 'xyz11228' - } - { - 'product': 'Karcher Hose Set', - 'total_value': 66, - 'quantity': 3, - 'product_id': 'def45678' - } - - The result documents contain details about the total value and - quantity of orders for products that cost more than $15. - -To view the complete code for this tutorial, see the `Completed Unpack Arrays App -`__ -on GitHub. From 613fd6fe0e014943eacac59c378a93a1c83ab242 Mon Sep 17 00:00:00 2001 From: norareidy Date: Tue, 17 Jun 2025 16:06:47 -0400 Subject: [PATCH 2/3] redirects --- config/redirects | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/config/redirects b/config/redirects index 888fd165..ed07f30c 100644 --- a/config/redirects +++ b/config/redirects @@ -1,5 +1,6 @@ define: prefix docs/languages/python/pymongo-driver define: base https://www.mongodb.com/${prefix} +define: server https://www.mongodb.com/docs/manual define: versions v4.0 v4.1 v4.2 v4.3 v4.4 v4.5 v4.6 v4.7 v4.8 v4.9 v4.10 v4.11 v4.12 v4.13 master symlink: current -> master @@ -169,10 +170,16 @@ raw: ${prefix}/security/authentication/kerberos/ -> ${base}/current/security/aut [*-master]: ${prefix}/${version}/indexes/wildcard-index/ -> ${base}/${version}/indexes/ [*-master]: ${prefix}/${version}/indexes/clustered-index/ -> ${base}/${version}/indexes/ +# Aggregation tutorials redirects [*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/ -> ${base}/${version}/aggregation/ -[*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/filtered-subset/ -> ${base}/${version}/aggregation/filtered-subset/ -[*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/group-total/ -> ${base}/${version}/aggregation/group-total/ -[*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/multi-field-join/ -> ${base}/${version}/aggregation/multi-field-join/ -[*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/one-to-one-join/ -> ${base}/${version}/aggregation/one-to-one-join/ -[*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/unpack-arrays/ -> ${base}/${version}/aggregation/unpack-arrays/ +[*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/filtered-subset/ -> ${server}/tutorial/aggregation-examples/filtered-subset/ +[*-master]: ${prefix}/${version}/aggregation/filtered-subset/ -> ${server}/tutorial/aggregation-examples/filtered-subset/ +[*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/group-total/ -> ${server}/tutorial/aggregation-examples/group-and-total/ +[*-master]: ${prefix}/${version}/aggregation/group-total/ -> ${server}/tutorial/aggregation-examples/group-and-total/ +[*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/multi-field-join/ -> ${server}/tutorial/aggregation-examples/multi-field-join/ +[*-master]: ${prefix}/${version}/aggregation/multi-field-join/ -> ${server}/tutorial/aggregation-examples/multi-field-join/ +[*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/one-to-one-join/ ->${server}/tutorial/aggregation-examples/one-to-one-join/ +[*-master]: ${prefix}/${version}/aggregation/one-to-one-join/ -> ${server}/tutorial/aggregation-examples/one-to-one-join/ +[*-master]: ${prefix}/${version}/aggregation/aggregation-tutorials/unpack-arrays/ -> ${server}/tutorial/aggregation-examples/unpack-arrays/ +[*-master]: ${prefix}/${version}/aggregation/unpack-arrays/ -> ${server}/tutorial/aggregation-examples/unpack-arrays/ From 8c5510b309dcf1cb5138f754a36f5038299fea04 Mon Sep 17 00:00:00 2001 From: norareidy Date: Tue, 17 Jun 2025 16:08:43 -0400 Subject: [PATCH 3/3] build error --- source/reference.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/reference.txt b/source/reference.txt index 4863c166..a171795b 100644 --- a/source/reference.txt +++ b/source/reference.txt @@ -17,8 +17,8 @@ Reference To find information about versioning, upgrading your driver, and migrating to the asynchronous driver, see the following pages: - - :ref:`Release Notes ` - - :ref:`Compatibility ` - - :ref:`Upgrade Guides ` - - :ref:`Migrate to PyMongo Async ` - - :ref:`Previous Versions ` \ No newline at end of file +- :ref:`Release Notes ` +- :ref:`Compatibility ` +- :ref:`Upgrade Guides ` +- :ref:`Migrate to PyMongo Async ` +- :ref:`Previous Versions ` \ No newline at end of file