@@ -132,8 +132,10 @@ Belongs To
132132A ``belongs_to`` macro is used when a document is the child in a ``has_one``
133133or ``has_many`` association. By default, in order for a document to
134134be saved, each of its ``belongs_to`` associations must be provided a value.
135- To override this requirement, you can use the option ``optional: false``
136- on the ``belong_to`` association.
135+ To override this requirement for a particular association, use the option
136+ ``optional: false`` on the ``belong_to`` association. To override this
137+ requirement globally, set the ``belongs_to_required_by_default``
138+ :ref:`configuration option <configuration-options>` to ``false``.
137139
138140Defining
139141~~~~~~~~
@@ -726,6 +728,8 @@ to the association.
726728
727729 band.save # Fires all save callbacks on the band, albums, and label.
728730
731+ .. _dependent-behavior:
732+
729733Dependent Behavior
730734******************
731735
@@ -1149,3 +1153,115 @@ the ``_id`` field which is then used to load full models. An alternative is
11491153to not perform such a projection and work with raw fields, which would eliminate
11501154having to send the list of document ids to Mongoid in the second query
11511155(which could be large).
1156+
1157+ .. _aggregation-pipeline-builder-dsl:
1158+
1159+ Aggregation Pipeline Builder DSL
1160+ ********************************
1161+
1162+ Mongoid provides limited support for constructing the aggregation pipeline
1163+ itself using a high-level DSL. The following aggregation pipeline operators
1164+ are supported:
1165+
1166+ - `$group <https://docs.mongodb.com/manual/reference/operator/aggregation/group/>`_
1167+ - `$project <https://docs.mongodb.com/manual/reference/operator/aggregation/project/>`_
1168+ - `$unwind <https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/>`_
1169+
1170+ To construct a pipeline, call the corresponding aggregation pipeine methods
1171+ on a ``Criteria`` instance. Aggregation pipeline operations are added to the
1172+ ``pipeline`` attribute of the ``Criteria`` instance. To execute the pipeline,
1173+ pass the ``pipeline`` attribute value to ``Collection#aggragegate`` method.
1174+
1175+ For example, given the following models:
1176+
1177+ .. code-block:: ruby
1178+
1179+ class Tour
1180+ include Mongoid::Document
1181+
1182+ embeds_many :participants
1183+
1184+ field :name, type: String
1185+ field :states, type: Array
1186+ end
1187+
1188+ class Participant
1189+ include Mongoid::Document
1190+
1191+ embedded_in :tour
1192+
1193+ field :name, type: String
1194+ end
1195+
1196+ We could find out which states a participant visited:
1197+
1198+ .. code-block:: ruby
1199+
1200+ criteria = Tour.where('participants.name' => 'Serenity',).
1201+ unwind(:states).
1202+ group(_id: 'states', :states.add_to_set => '$states').
1203+ project(_id: 0, states: 1)
1204+
1205+ pp criteria.pipeline
1206+ # => [{"$match"=>{"participants.name"=>"Serenity"}},
1207+ # {"$unwind"=>"$states"},
1208+ # {"$group"=>{"_id"=>"states", "states"=>{"$addToSet"=>"$states"}}},
1209+ # {"$project"=>{"_id"=>0, "states"=>1}}]
1210+
1211+ Tour.collection.aggregate(criteria.pipeline).to_a
1212+
1213+ group
1214+ ~~~~~
1215+
1216+ The ``group`` method adds a `$group aggregation pipeline stage
1217+ <https://docs.mongodb.com/manual/reference/operator/aggregation/group/>`_.
1218+
1219+ The field expressions support Mongoid symbol-operator syntax:
1220+
1221+ .. code-block:: ruby
1222+
1223+ criteria = Tour.all.group(_id: 'states', :states.add_to_set => '$states')
1224+ criteria.pipeline
1225+ # => [{"$group"=>{"_id"=>"states", "states"=>{"$addToSet"=>"$states"}}}]
1226+
1227+ Alternatively, standard MongoDB aggregation pipeline syntax may be used:
1228+
1229+ .. code-block:: ruby
1230+
1231+ criteria = Tour.all.group(_id: 'states', states: {'$addtoSet' => '$states'})
1232+
1233+ project
1234+ ~~~~~~~
1235+
1236+ The ``project`` method adds a `$project aggregation pipeline stage
1237+ <https://docs.mongodb.com/manual/reference/operator/aggregation/project/>`_.
1238+
1239+ The argument should be a Hash specifying the projection:
1240+
1241+ .. code-block:: ruby
1242+
1243+ criteria = Tour.all.project(_id: 0, states: 1)
1244+ criteria.pipeline
1245+ # => [{"$project"=>{"_id"=>0, "states"=>1}}]
1246+
1247+ .. _unwind-dsl:
1248+
1249+ unwind
1250+ ~~~~~~
1251+
1252+ The ``unwind`` method adds an `$unwind aggregation pipeline stage
1253+ <https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/>`_.
1254+
1255+ The argument can be a field name, specifyable as a symbol or a string, or
1256+ a Hash or a ``BSON::Document`` instance:
1257+
1258+ .. code-block:: ruby
1259+
1260+ criteria = Tour.all.unwind(:states)
1261+ criteria = Tour.all.unwind('states')
1262+ criteria.pipeline
1263+ # => [{"$unwind"=>"$states"}]
1264+
1265+ criteria = Tour.all.unwind(path: '$states')
1266+ criteria.pipeline
1267+ # => [{"$unwind"=>{:path=>"$states"}}]
0 commit comments