|
| 1 | +.. _mongoid-aggregation: |
| 2 | + |
| 3 | +==================================== |
| 4 | +Transform Your Data with Aggregation |
| 5 | +==================================== |
| 6 | + |
| 7 | +.. facet:: |
| 8 | + :name: genre |
| 9 | + :values: reference |
| 10 | + |
| 11 | +.. meta:: |
| 12 | + :keywords: code example, transform, pipeline |
| 13 | + |
| 14 | +.. contents:: On this page |
| 15 | + :local: |
| 16 | + :backlinks: none |
| 17 | + :depth: 1 |
| 18 | + :class: singlecol |
| 19 | + |
| 20 | +Overview |
| 21 | +-------- |
| 22 | + |
| 23 | +In this guide, you can learn how to use {+odm+} to perform **aggregation |
| 24 | +operations**. |
| 25 | + |
| 26 | +Aggregation operations process data in your MongoDB collections and return |
| 27 | +computed results. The MongoDB Aggregation framework, which is part of the Query |
| 28 | +API, is modeled on the concept of data processing pipelines. Documents enter a |
| 29 | +pipeline that contains one or more stages, and this pipeline transforms the |
| 30 | +documents into an aggregated result. |
| 31 | + |
| 32 | +An aggregation operation is similar to a car factory. A car factory has an assembly line, which contains assembly stations with specialized tools to do specific jobs, like drills and welders. Raw parts enter the factory, and then the assembly line transforms and assembles them into a finished product. |
| 33 | + |
| 34 | +The **aggregation pipeline** is the assembly line, **aggregation stages** are the |
| 35 | +assembly stations, and **operator expressions** are the specialized tools. |
| 36 | + |
| 37 | +Aggregation Versus Find Operations |
| 38 | +---------------------------------- |
| 39 | + |
| 40 | +You can use find operations to perform the following actions: |
| 41 | + |
| 42 | +- Select which documents to return |
| 43 | +- Select which fields to return |
| 44 | +- Sort the results |
| 45 | + |
| 46 | +You can use aggregation operations to perform the following actions: |
| 47 | + |
| 48 | +- Run find operations |
| 49 | +- Rename fields |
| 50 | +- Summarize data |
| 51 | +- Group values |
| 52 | + |
| 53 | +{+odm+} Builders |
| 54 | +---------------- |
| 55 | + |
| 56 | +You can construct an aggregation pipeline by using {+odm+}'s high-level |
| 57 | +domain-specific language (DSL). The DSL supports the following aggregation |
| 58 | +pipeline operators: |
| 59 | + |
| 60 | +.. list-table:: |
| 61 | + :header-rows: 1 |
| 62 | + :widths: 10 90 |
| 63 | + :class: table-bordered |
| 64 | + |
| 65 | + * - Operator |
| 66 | + - Method Name |
| 67 | + |
| 68 | + * - :manual:`$group <reference/operator/aggregation/group/>` |
| 69 | + - ``group()`` |
| 70 | + |
| 71 | + * - :manual:`$project <reference/operator/aggregation/project/>` |
| 72 | + - ``project()`` |
| 73 | + |
| 74 | + * - :manual:`$unwind <reference/operator/aggregation/unwind/>` |
| 75 | + - ``unwind()`` |
| 76 | + |
| 77 | +To create an aggregation pipeline by using one of the preceding operators, call |
| 78 | +the corresponding method on an instance of ``Criteria``. Calling the method adds |
| 79 | +the aggregation operation to the ``pipelin`` atrritbure of the ``Criteria`` |
| 80 | +instance. To run the aggregation pipeline, pass the ``pipeline`` attribute value |
| 81 | +to the ``Collection#aggregate()`` method. |
| 82 | + |
| 83 | +Example |
| 84 | +~~~~~~~ |
| 85 | + |
| 86 | +Consider a collection that contains documents that are modeled as follows: |
| 87 | + |
| 88 | +.. code-block:: ruby |
| 89 | + |
| 90 | + class Tour |
| 91 | + include Mongoid::Document |
| 92 | + |
| 93 | + embeds_many :participants |
| 94 | + |
| 95 | + field :name, type: String |
| 96 | + field :states, type: Array |
| 97 | + end |
| 98 | + |
| 99 | + class Participant |
| 100 | + include Mongoid::Document |
| 101 | + |
| 102 | + embedded_in :tour |
| 103 | + |
| 104 | + field :name, type: String |
| 105 | + end |
| 106 | + |
| 107 | +The following example creates an aggregation pipeline that outputs the states a |
| 108 | +participant has visited by using the following |
| 109 | +aggregation operations: |
| 110 | + |
| 111 | +- ``$match``, which find documents in which the ``participants.name`` field |
| 112 | + value is ``"Serenity"`` |
| 113 | +- ``$unwind``, which deconstructs the ``states`` array field and outputs a |
| 114 | + document for each element in the array |
| 115 | +- ``$group``, which groups the documents by the value of their ``states`` field |
| 116 | +- ``$project``, which prompts the pipeline to return only the ``_id`` and |
| 117 | + ``states`` fields |
| 118 | + |
| 119 | +.. literalinclude:: /includes/aggregation/builder-dsl.rb |
| 120 | + :language: ruby |
| 121 | + |
| 122 | +Aggregation with the Ruby Driver |
| 123 | +-------------------------------- |
| 124 | + |
| 125 | +You can use the Ruby driver to run aggregation operations that do not have |
| 126 | +corresponding builder methods by using the |
| 127 | +``Collection#aggregate()`` method, and passing in an array of aggregation |
| 128 | +operations. Creating the aggregation pipeline by using the Ruby driver returns |
| 129 | +raw ``BSON::Document`` objects rather than ``Mongoid::Document`` model |
| 130 | +instances. |
| 131 | + |
| 132 | +Example |
| 133 | +~~~~~~~ |
| 134 | + |
| 135 | +Consider a collection that contains documents that are modeled as follows: |
| 136 | + |
| 137 | +.. code-block:: ruby |
| 138 | + |
| 139 | + class Band |
| 140 | + include Mongoid::Document |
| 141 | + has_many :tours |
| 142 | + has_many :awards |
| 143 | + field :name, type: String |
| 144 | + end |
| 145 | + |
| 146 | + class Tour |
| 147 | + include Mongoid::Document |
| 148 | + belongs_to :band |
| 149 | + field :year, type: Integer |
| 150 | + end |
| 151 | + |
| 152 | + class Award |
| 153 | + include Mongoid::Document |
| 154 | + belongs_to :band |
| 155 | + field :name, type: String |
| 156 | + end |
| 157 | + |
| 158 | +The following example creates an aggregation pipeline to retrieve all bands that |
| 159 | +have toured since 2010 and have at least one or more awards: |
| 160 | + |
| 161 | +.. literalinclude:: /includes/aggregation/ruby-aggregation.rb |
| 162 | + :language: ruby |
| 163 | + |
| 164 | +.. tip:: |
| 165 | + |
| 166 | + The preceding example projects only the ``_id`` field of the output |
| 167 | + documents. It then uses the ``_id`` field to find the documents and return |
| 168 | + them as ``Mongoid::Document`` model instances. This optional step is not |
| 169 | + required to run an aggregation pipeline. |
| 170 | + |
| 171 | +Additional Information |
| 172 | +---------------------- |
| 173 | + |
| 174 | +To view a full list of aggregation operators, see :manual:`Aggregation |
| 175 | +Operators. </reference/operator/aggregation/>` |
| 176 | + |
| 177 | +To learn about assembling an aggregation pipeline and view examples, see |
| 178 | +:manual:`Aggregation Pipeline. </core/aggregation-pipeline/>` |
| 179 | + |
| 180 | +To learn more about creating pipeline stages, see :manual:`Aggregation |
| 181 | +Stages. </reference/operator/aggregation-pipeline/>` |
| 182 | + |
| 183 | +API Documentation |
| 184 | +~~~~~~~~~~~~~~~~~ |
| 185 | + |
| 186 | +To learn more about any of the methods discussed in this |
| 187 | +guide, see the following API documentation: |
| 188 | + |
| 189 | +- `group() <{+api-root+}/Criteria/Queryable/Aggregable.html#group-instance_method>`__ |
| 190 | +- `project() <{+api-root+}/Criteria/Queryable/Aggregable.html#project-instance_method>`__ |
| 191 | +- `unwind() <{+api-root+}/Criteria/Queryable/Aggregable.html#unwind-instance_method>`__ |
0 commit comments