@@ -1637,180 +1637,3 @@ with, and is useful for developers of extensions to Mongoid.
1637
1637
- Returns the name of the field to set the polymorphic type.
1638
1638
* - ``Association#validate?``
1639
1639
- 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