@@ -241,6 +241,68 @@ to the other in the form of an array.
241
241
"band_ids" : [ ObjectId("4d3ed089fb60ab534684b7e9") ]
242
242
}
243
243
244
+
245
+ Querying Referenced Associations
246
+ --------------------------------
247
+
248
+ In most cases, efficient queries across referenced associations (and in general
249
+ involving data or conditions or multiple collections) are performed using
250
+ the aggregation pipeline. Mongoid helpers for constructing aggregation pipeline
251
+ queries are described in the :ref:`aggregation pipeline <aggregation-pipeline>`
252
+ section.
253
+
254
+ For simple queries, the use of aggregation pipeline may be avoided and
255
+ associations may be queried directly. When querying associations directly,
256
+ all conditions must be on that association's collection only (which typically
257
+ means association in question and any associations embedded in it).
258
+
259
+ For example, given the following models:
260
+
261
+ .. code-block:: ruby
262
+
263
+ class Band
264
+ include Mongoid::Document
265
+
266
+ has_many :tours
267
+ has_many :awards
268
+
269
+ field :name, type: String
270
+ end
271
+
272
+ class Tour
273
+ include Mongoid::Document
274
+
275
+ belongs_to :band
276
+
277
+ field :year, type: Integer
278
+ end
279
+
280
+ class Award
281
+ include Mongoid::Document
282
+
283
+ belongs_to :band
284
+
285
+ field :name, type: String
286
+ end
287
+
288
+ One could retrieve all bands that have toured since 2000 as follows:
289
+
290
+ .. code-block:: ruby
291
+
292
+ band_ids = Tour.where(year: {'$gte' => 2000}).pluck(:band_id)
293
+ bands = Band.find(band_ids)
294
+
295
+ The conditions on ``Tour`` can be arbitrarily complex, but they must all
296
+ be on the same ``Tour`` document (or documents embedded in ``Tour``).
297
+
298
+ To find awards for bands that have toured since 2000:
299
+
300
+ .. code-block:: ruby
301
+
302
+ band_ids = Tour.where(year: {'$gte' => 2000}).pluck(:band_id)
303
+ awards = Award.where(band_id: {'$in' => band_ids})
304
+
305
+
244
306
Embedded Associations
245
307
=====================
246
308
@@ -442,6 +504,92 @@ help of MongoDB projection operation:
442
504
Band.where(started_on: {'$gt' => Time.now - 1.year}).only(:label).map(&:label).compact.uniq
443
505
444
506
507
+ Querying Embedded Associations
508
+ ------------------------------
509
+
510
+ When querying top-level documents, conditions can be specified on documents
511
+ in embedded associations using the dot notation. For example, given the
512
+ following models:
513
+
514
+ .. code-block:: ruby
515
+
516
+ class Band
517
+ include Mongoid::Document
518
+ embeds_many :tours
519
+ embeds_many :awards
520
+ field :name, type: String
521
+ end
522
+
523
+ class Tour
524
+ include Mongoid::Document
525
+ embedded_in :band
526
+ field :year, type: Integer
527
+ end
528
+
529
+ class Award
530
+ include Mongoid::Document
531
+ embedded_in :band
532
+ field :name, type: String
533
+ end
534
+
535
+ To retrieve bands based on tour attributes, use the dot notation as follows:
536
+
537
+ .. code-block:: ruby
538
+
539
+ # Get all bands that have toured since 2000
540
+ Band.where('tours.year' => {'$gte' => 2000})
541
+
542
+ To retrieve only documents of embedded associations, without retrieving
543
+ top-level documents, use the ``pluck`` projection method:
544
+
545
+ .. code-block:: ruby
546
+
547
+ # Get awards for bands that have toured since 2000
548
+ Band.where('tours.year' => {'$gte' => 2000}).pluck(:awards)
549
+
550
+ .. _embedded-matching:
551
+
552
+ Querying Loaded Associations
553
+ ````````````````````````````
554
+
555
+ Mongoid query methods can be used on embedded associations of documents which
556
+ are already loaded in the application. This mechanism is sometimes called
557
+ "embedded matching" or "embedded document matching" and it is implemented
558
+ entirely in Mongoid - the queries are NOT sent to the server.
559
+
560
+ Embedded matching is supported for most general-purpose query operators. It
561
+ is not implemented for :ref:`text search <text-search>`, :manual:`geospatial query
562
+ operators </reference/operator/query-geospatial/>`,
563
+ operators that execute JavaScript code (:manual:`$where </reference/operator/query/where/>`)
564
+ and operators that are implemented via other server functionality such as
565
+ :manual:`$expr <https://docs.mongodb.com/manual/reference/operator/query/expr/>`
566
+ and :manual:`$jsonSchema <https://docs.mongodb.com/manual/reference/operator/query/jsonSchema/>`.
567
+ The following operators are supported:
568
+
569
+ - :manual:`Comparison operators </reference/operator/query-comparison/>`.
570
+ - :manual:`Logical operators </reference/operator/query-logical/>`.
571
+ - :manual:`$exists </reference/operator/query/exists/>`
572
+ (:manual:`$type </reference/operator/query/type/>` is not currently supported).
573
+ - :manual:`$regex </reference/operator/query/regex/>` (``$options`` field
574
+ is not currently supported, the options must be given as part of the
575
+ regular expression object).
576
+ - :manual:`Array query operators </reference/operator/query-array/>`.
577
+
578
+ For example, using the model definitions just given, we could query
579
+ tours on a loaded band:
580
+
581
+ .. code-block:: ruby
582
+
583
+ band = Band.where(name: 'Astral Projection').first
584
+ tours = band.tours.where(year: {'$gte' => 2000})
585
+
586
+ .. note::
587
+
588
+ Mongoid aims to provide the same semantics when performing embedded matching
589
+ as those of MongoDB server. This means, for example, that embedded matchers
590
+ generally support arguments of the same types as ``Criteria`` methods do.
591
+
592
+
445
593
Common Behavior
446
594
===============
447
595
@@ -996,104 +1144,10 @@ with, and is useful for developers of extensions to Mongoid.
996
1144
- Returns whether the association has an associated validation.
997
1145
998
1146
999
- Querying Associations
1000
- =====================
1001
-
1002
- Mongoid supports several forms of efficient querying of documents based on
1003
- associations.
1004
-
1005
-
1006
- Embedded Associations
1007
- ---------------------
1008
-
1009
- Given the following models:
1010
-
1011
- .. code-block:: ruby
1012
-
1013
- class Band
1014
- include Mongoid::Document
1015
- embeds_many :tours
1016
- embeds_many :awards
1017
- field :name, type: String
1018
- end
1019
-
1020
- class Tour
1021
- include Mongoid::Document
1022
- embedded_in :band
1023
- field :year, type: Integer
1024
- end
1025
-
1026
- class Award
1027
- include Mongoid::Document
1028
- embedded_in :band
1029
- field :name, type: String
1030
- end
1031
-
1032
- Mongoid allows retrieving bands whose tours have certain attributes via the
1033
- dot notation, as follows:
1034
-
1035
- .. code-block:: ruby
1036
-
1037
- # Get all bands that have toured since 2000
1038
- Band.where('tours.year' => {'$gte' => 2000})
1039
-
1040
- Mongoid also can retrieve embedded documents only, without retrieving top-level
1041
- documents, using projection:
1042
-
1043
- .. code-block:: ruby
1044
-
1045
- # Get awards for bands that have toured since 2000
1046
- Band.where('tours.year' => {'$gte' => 2000}).pluck(:awards)
1047
-
1048
-
1049
- Referenced Associations
1050
- -----------------------
1051
-
1052
- If the associations are referenced rather than embedded, performing queries
1053
- through them takes a bit more work. Given the following models modified from
1054
- the previous example:
1055
-
1056
- .. code-block:: ruby
1057
-
1058
- class Band
1059
- include Mongoid::Document
1060
- has_many :tours
1061
- has_many :awards
1062
- field :name, type: String
1063
- end
1064
-
1065
- class Tour
1066
- include Mongoid::Document
1067
- belongs_to :band
1068
- field :year, type: Integer
1069
- end
1070
-
1071
- class Award
1072
- include Mongoid::Document
1073
- belongs_to :band
1074
- field :name, type: String
1075
- end
1076
-
1077
- One could retrieve all bands that have toured since 2000 as follows:
1078
-
1079
- .. code-block:: ruby
1080
-
1081
- band_ids = Tour.where(year: {'$gte' => 2000}).pluck(:band_id)
1082
- bands = Band.find(band_ids)
1083
-
1084
- The conditions on ``Tour`` can be arbitrarily complex, but they must all
1085
- be on the same ``Tour`` document (or documents embedded in ``Tour``).
1086
-
1087
- To find awards for bands that have toured since 2000:
1088
-
1089
- .. code-block:: ruby
1090
-
1091
- band_ids = Tour.where(year: {'$gte' => 2000}).pluck(:band_id)
1092
- awards = Award.where(band_id: {'$in' => band_ids})
1093
-
1147
+ .. _aggregation-pipeline:
1094
1148
1095
1149
Aggregation Pipeline
1096
- --------------------
1150
+ ====================
1097
1151
1098
1152
Mongoid exposes MongoDB's aggregation pipeline for queries involving multiple
1099
1153
referenced associations at the same time. Given the same setup as before with
@@ -1156,8 +1210,8 @@ having to send the list of document ids to Mongoid in the second query
1156
1210
1157
1211
.. _aggregation-pipeline-builder-dsl:
1158
1212
1159
- Aggregation Pipeline Builder DSL
1160
- --------------------------------
1213
+ Builder DSL
1214
+ -----------
1161
1215
1162
1216
Mongoid provides limited support for constructing the aggregation pipeline
1163
1217
itself using a high-level DSL. The following aggregation pipeline operators
0 commit comments