@@ -1637,180 +1637,3 @@ with, and is useful for developers of extensions to Mongoid.
16371637 - Returns the name of the field to set the polymorphic type.
16381638 * - ``Association#validate?``
16391639 - Returns whether the association has an associated validation.
1640-
1641-
1642- .. _aggregation-pipeline:
1643-
1644- Aggregation Pipeline
1645- ====================
1646-
1647- Mongoid exposes MongoDB's aggregation pipeline for queries involving multiple
1648- referenced associations at the same time. Given the same setup as before with
1649- referenced associations:
1650-
1651- .. code-block:: ruby
1652-
1653- class Band
1654- include Mongoid::Document
1655- has_many :tours
1656- has_many :awards
1657- field :name, type: String
1658- end
1659-
1660- class Tour
1661- include Mongoid::Document
1662- belongs_to :band
1663- field :year, type: Integer
1664- end
1665-
1666- class Award
1667- include Mongoid::Document
1668- belongs_to :band
1669- field :name, type: String
1670- end
1671-
1672- To retrieve bands that toured since 2000 and have at least one award, one
1673- could do the following:
1674-
1675- .. code-block:: ruby
1676-
1677- band_ids = Band.collection.aggregate([
1678- {'$lookup' => {
1679- from: 'tours',
1680- localField: '_id',
1681- foreignField: 'band_id',
1682- as: 'tours',
1683- }},
1684- {'$lookup' => {
1685- from: 'awards',
1686- localField: '_id',
1687- foreignField: 'band_id',
1688- as: 'awards',
1689- }},
1690- {'$match' => {
1691- 'tours.year' => {'$gte' => 2000},
1692- 'awards._id' => {'$exists' => true},
1693- }},
1694- {'$project' => {_id: 1}},
1695- ])
1696- bands = Band.find(band_ids)
1697-
1698- Note that the aggregation pipeline, since it is implemented by the Ruby driver
1699- for MongoDB and not Mongoid, returns raw ``BSON::Document`` objects rather than
1700- ``Mongoid::Document`` model instances. The above example projects only
1701- the ``_id`` field which is then used to load full models. An alternative is
1702- to not perform such a projection and work with raw fields, which would eliminate
1703- having to send the list of document ids to Mongoid in the second query
1704- (which could be large).
1705-
1706- .. _aggregation-pipeline-builder-dsl:
1707-
1708- Builder DSL
1709- -----------
1710-
1711- Mongoid provides limited support for constructing the aggregation pipeline
1712- itself using a high-level DSL. The following aggregation pipeline operators
1713- are supported:
1714-
1715- - `$group <https://mongodb.com/docs/manual/reference/operator/aggregation/group/>`_
1716- - `$project <https://mongodb.com/docs/manual/reference/operator/aggregation/project/>`_
1717- - `$unwind <https://mongodb.com/docs/manual/reference/operator/aggregation/unwind/>`_
1718-
1719- To construct a pipeline, call the corresponding aggregation pipeline methods
1720- on a ``Criteria`` instance. Aggregation pipeline operations are added to the
1721- ``pipeline`` attribute of the ``Criteria`` instance. To execute the pipeline,
1722- pass the ``pipeline`` attribute value to ``Collection#aggragegate`` method.
1723-
1724- For example, given the following models:
1725-
1726- .. code-block:: ruby
1727-
1728- class Tour
1729- include Mongoid::Document
1730-
1731- embeds_many :participants
1732-
1733- field :name, type: String
1734- field :states, type: Array
1735- end
1736-
1737- class Participant
1738- include Mongoid::Document
1739-
1740- embedded_in :tour
1741-
1742- field :name, type: String
1743- end
1744-
1745- We could find out which states a participant visited:
1746-
1747- .. code-block:: ruby
1748-
1749- criteria = Tour.where('participants.name' => 'Serenity',).
1750- unwind(:states).
1751- group(_id: 'states', :states.add_to_set => '$states').
1752- project(_id: 0, states: 1)
1753-
1754- pp criteria.pipeline
1755- # => [{"$match"=>{"participants.name"=>"Serenity"}},
1756- # {"$unwind"=>"$states"},
1757- # {"$group"=>{"_id"=>"states", "states"=>{"$addToSet"=>"$states"}}},
1758- # {"$project"=>{"_id"=>0, "states"=>1}}]
1759-
1760- Tour.collection.aggregate(criteria.pipeline).to_a
1761-
1762- group
1763- `````
1764-
1765- The ``group`` method adds a `$group aggregation pipeline stage
1766- <https://mongodb.com/docs/manual/reference/operator/aggregation/group/>`_.
1767-
1768- The field expressions support Mongoid symbol-operator syntax:
1769-
1770- .. code-block:: ruby
1771-
1772- criteria = Tour.all.group(_id: 'states', :states.add_to_set => '$states')
1773- criteria.pipeline
1774- # => [{"$group"=>{"_id"=>"states", "states"=>{"$addToSet"=>"$states"}}}]
1775-
1776- Alternatively, standard MongoDB aggregation pipeline syntax may be used:
1777-
1778- .. code-block:: ruby
1779-
1780- criteria = Tour.all.group(_id: 'states', states: {'$addToSet' => '$states'})
1781-
1782- project
1783- ```````
1784-
1785- The ``project`` method adds a `$project aggregation pipeline stage
1786- <https://mongodb.com/docs/manual/reference/operator/aggregation/project/>`_.
1787-
1788- The argument should be a Hash specifying the projection:
1789-
1790- .. code-block:: ruby
1791-
1792- criteria = Tour.all.project(_id: 0, states: 1)
1793- criteria.pipeline
1794- # => [{"$project"=>{"_id"=>0, "states"=>1}}]
1795-
1796- .. _unwind-dsl:
1797-
1798- unwind
1799- ``````
1800-
1801- The ``unwind`` method adds an `$unwind aggregation pipeline stage
1802- <https://mongodb.com/docs/manual/reference/operator/aggregation/unwind/>`_.
1803-
1804- The argument can be a field name, specifiable as a symbol or a string, or
1805- a Hash or a ``BSON::Document`` instance:
1806-
1807- .. code-block:: ruby
1808-
1809- criteria = Tour.all.unwind(:states)
1810- criteria = Tour.all.unwind('states')
1811- criteria.pipeline
1812- # => [{"$unwind"=>"$states"}]
1813-
1814- criteria = Tour.all.unwind(path: '$states')
1815- criteria.pipeline
1816- # => [{"$unwind"=>{:path=>"$states"}}]
0 commit comments