-
Notifications
You must be signed in to change notification settings - Fork 29
DOCSP-42767 Aggregation #57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
eff4e1d
b006dfb
df09491
0d50df7
420c82f
fc7447b
0659cc6
61f460f
006ff36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,190 @@ | ||||||||||
.. _mongoid-aggregation: | ||||||||||
|
||||||||||
==================================== | ||||||||||
Transform Your Data with Aggregation | ||||||||||
==================================== | ||||||||||
|
||||||||||
.. facet:: | ||||||||||
:name: genre | ||||||||||
:values: reference | ||||||||||
|
||||||||||
.. meta:: | ||||||||||
:keywords: code example, transform, pipeline | ||||||||||
|
||||||||||
.. contents:: On this page | ||||||||||
:local: | ||||||||||
:backlinks: none | ||||||||||
:depth: 1 | ||||||||||
:class: singlecol | ||||||||||
|
||||||||||
Overview | ||||||||||
-------- | ||||||||||
|
||||||||||
In this guide, you can learn how to use {+odm+} to perform **aggregation | ||||||||||
operations**. | ||||||||||
|
||||||||||
Aggregation operations process data in your MongoDB collections and return | ||||||||||
computed results. The MongoDB Aggregation framework, which is part of the Query | ||||||||||
API, is modeled on the concept of data processing pipelines. Documents enter a | ||||||||||
pipeline that contains one or more stages, and this pipeline transforms the | ||||||||||
documents into an aggregated result. | ||||||||||
|
||||||||||
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. | ||||||||||
Check failure on line 32 in source/aggregation.txt
|
||||||||||
rustagir marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
rustagir marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
The **aggregation pipeline** is the assembly line, **aggregation stages** are the | ||||||||||
assembly stations, and **operator expressions** are the specialized tools. | ||||||||||
|
||||||||||
Aggregation Versus Find Operations | ||||||||||
---------------------------------- | ||||||||||
|
||||||||||
You can use find operations to perform the following actions: | ||||||||||
|
||||||||||
- Select which documents to return | ||||||||||
- Select which fields to return | ||||||||||
- Sort the results | ||||||||||
|
||||||||||
You can use aggregation operations to perform the following actions: | ||||||||||
|
||||||||||
- Run find operations | ||||||||||
- Rename fields | ||||||||||
- Summarize data | ||||||||||
- Group values | ||||||||||
|
||||||||||
|
||||||||||
{+odm+} Builders | ||||||||||
---------------- | ||||||||||
|
||||||||||
You can construct an aggregation pipeline by using {+odm+}'s high-level | ||||||||||
domain-specific language (DSL). The DSL supports the following aggregation | ||||||||||
pipeline operators: | ||||||||||
|
||||||||||
.. list-table:: | ||||||||||
:header-rows: 1 | ||||||||||
:widths: 50 50 | ||||||||||
|
||||||||||
* - Operator | ||||||||||
- Method Name | ||||||||||
|
||||||||||
* - :manual:`$group <reference/operator/aggregation/group/>` | ||||||||||
- ``group()`` | ||||||||||
|
||||||||||
* - :manual:`$project <reference/operator/aggregation/project/>` | ||||||||||
- ``project()`` | ||||||||||
|
||||||||||
* - :manual:`$unwind <reference/operator/aggregation/unwind/>` | ||||||||||
- ``unwind()`` | ||||||||||
|
||||||||||
To create an aggregation pipeline by using one of the preceding operators, call | ||||||||||
the corresponding method on an instance of ``Criteria``. Calling the method adds | ||||||||||
the aggregation operation to the ``pipeline`` atrritbure of the ``Criteria`` | ||||||||||
instance. To run the aggregation pipeline, pass the ``pipeline`` attribute value | ||||||||||
to the ``Collection#aggregate()`` method. | ||||||||||
|
||||||||||
Example | ||||||||||
~~~~~~~ | ||||||||||
|
||||||||||
Consider a collection that contains documents that are modeled as follows: | ||||||||||
rustagir marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
.. code-block:: ruby | ||||||||||
|
||||||||||
class Tour | ||||||||||
include Mongoid::Document | ||||||||||
|
||||||||||
embeds_many :participants | ||||||||||
|
||||||||||
field :name, type: String | ||||||||||
field :states, type: Array | ||||||||||
end | ||||||||||
|
||||||||||
class Participant | ||||||||||
include Mongoid::Document | ||||||||||
|
||||||||||
embedded_in :tour | ||||||||||
|
||||||||||
field :name, type: String | ||||||||||
end | ||||||||||
|
||||||||||
rustagir marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
The following example creates an aggregation pipeline that outputs the states a | ||||||||||
participant has visited by using the following | ||||||||||
aggregation operations: | ||||||||||
|
||||||||||
- ``$match``, which find documents in which the ``participants.name`` field | ||||||||||
value is ``"Serenity"`` | ||||||||||
- ``$unwind``, which deconstructs the ``states`` array field and outputs a | ||||||||||
document for each element in the array | ||||||||||
- ``$group``, which groups the documents by the value of their ``states`` field | ||||||||||
- ``$project``, which prompts the pipeline to return only the ``_id`` and | ||||||||||
``states`` fields | ||||||||||
rustagir marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
.. literalinclude:: /includes/aggregation/builder-dsl.rb | ||||||||||
:language: ruby | ||||||||||
|
||||||||||
|
||||||||||
Aggregation with the Ruby Driver | ||||||||||
-------------------------------- | ||||||||||
|
||||||||||
You can use the Ruby driver to run aggregation operations that do not have | ||||||||||
rustagir marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
corresponding builder methods by using the | ||||||||||
``Collection#aggregate()`` method and passing in an array of aggregation | ||||||||||
operations. Creating the aggregation pipeline by using the Ruby driver returns | ||||||||||
rustagir marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
raw ``BSON::Document`` objects rather than ``Mongoid::Document`` model | ||||||||||
instances. | ||||||||||
|
||||||||||
Example | ||||||||||
~~~~~~~ | ||||||||||
|
||||||||||
Consider a collection that contains documents that are modeled as follows: | ||||||||||
|
Consider a collection that contains documents that are modeled as follows: | |
Consider a database that contains collection with documents that are modeled by the following classes: |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The following example creates an aggregation pipeline to retrieve all bands that | |
have toured since 2000 and have at least one award: | |
The following example creates an aggregation pipeline to retrieve all bands that | |
have toured since ``2000`` and have at least ``1`` award: |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
S: same as above, include output
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
criteria = Tour.where('participants.name' => 'Serenity'). | ||
unwind(:states). | ||
group(_id: 'states', :states.add_to_set => '$states'). | ||
project(_id: 0, states: 1) | ||
|
||
Tour.collection.aggregate(criteria.pipeline).to_a | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
band_ids = Band.collection.aggregate([ | ||
{ '$lookup' => { | ||
from: 'tours', | ||
localField: '_id', | ||
foreignField: 'band_id', | ||
as: 'tours', | ||
} }, | ||
{ '$lookup' => { | ||
from: 'awards', | ||
localField: '_id', | ||
foreignField: 'band_id', | ||
as: 'awards', | ||
} }, | ||
{ '$match' => { | ||
'tours.year' => {'$gte' => 2000}, | ||
'awards._id' => {'$exists' => true}, | ||
} }, | ||
{'$project' => {_id: 1}}, | ||
]) | ||
|
||
bands = Band.find(band_ids.to_a) |
Uh oh!
There was an error while loading. Please reload this page.