mongoid 5.4.0 → 6.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +3 -3
- data/Rakefile +26 -0
- data/lib/config/locales/en.yml +40 -0
- data/lib/mongoid/atomic/modifiers.rb +2 -2
- data/lib/mongoid/atomic.rb +5 -5
- data/lib/mongoid/attributes/readonly.rb +22 -0
- data/lib/mongoid/attributes.rb +22 -21
- data/lib/mongoid/cacheable.rb +36 -0
- data/lib/mongoid/changeable.rb +36 -0
- data/lib/mongoid/clients/options.rb +55 -250
- data/lib/mongoid/clients/sessions.rb +113 -0
- data/lib/mongoid/clients/storage_options.rb +2 -69
- data/lib/mongoid/clients.rb +10 -63
- data/lib/mongoid/composable.rb +29 -2
- data/lib/mongoid/config.rb +1 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/atomic.rb +4 -4
- data/lib/mongoid/contextual/map_reduce.rb +7 -3
- data/lib/mongoid/contextual/memory.rb +9 -4
- data/lib/mongoid/contextual/mongo.rb +65 -30
- data/lib/mongoid/contextual/none.rb +12 -0
- data/lib/mongoid/copyable.rb +13 -6
- data/lib/mongoid/criteria/marshalable.rb +2 -2
- data/lib/mongoid/criteria/modifiable.rb +29 -3
- data/lib/mongoid/criteria/options.rb +25 -0
- data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
- data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
- data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
- data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
- data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
- data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +79 -0
- data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
- data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
- data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
- data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
- data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
- data/lib/mongoid/criteria/queryable/key.rb +103 -0
- data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
- data/lib/mongoid/criteria/queryable/mergeable.rb +273 -0
- data/lib/mongoid/criteria/queryable/optional.rb +429 -0
- data/lib/mongoid/criteria/queryable/options.rb +153 -0
- data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
- data/lib/mongoid/criteria/queryable/selectable.rb +689 -0
- data/lib/mongoid/criteria/queryable/selector.rb +212 -0
- data/lib/mongoid/criteria/queryable/smash.rb +104 -0
- data/lib/mongoid/criteria/queryable.rb +87 -0
- data/lib/mongoid/criteria.rb +6 -2
- data/lib/mongoid/document.rb +34 -41
- data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
- data/lib/mongoid/errors/invalid_field.rb +2 -2
- data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
- data/lib/mongoid/errors/invalid_relation.rb +66 -0
- data/lib/mongoid/errors/invalid_session_use.rb +24 -0
- data/lib/mongoid/errors.rb +3 -0
- data/lib/mongoid/evolvable.rb +1 -1
- data/lib/mongoid/extensions/big_decimal.rb +17 -8
- data/lib/mongoid/extensions/date.rb +4 -1
- data/lib/mongoid/extensions/decimal128.rb +3 -3
- data/lib/mongoid/extensions/hash.rb +1 -0
- data/lib/mongoid/extensions/regexp.rb +1 -0
- data/lib/mongoid/extensions/string.rb +6 -3
- data/lib/mongoid/extensions/time.rb +4 -1
- data/lib/mongoid/extensions.rb +0 -4
- data/lib/mongoid/factory.rb +2 -1
- data/lib/mongoid/fields/validators/macro.rb +18 -0
- data/lib/mongoid/findable.rb +2 -2
- data/lib/mongoid/indexable.rb +16 -14
- data/lib/mongoid/interceptable.rb +9 -22
- data/lib/mongoid/matchable/all.rb +2 -2
- data/lib/mongoid/matchable/and.rb +3 -3
- data/lib/mongoid/matchable/default.rb +2 -2
- data/lib/mongoid/matchable/elem_match.rb +28 -0
- data/lib/mongoid/matchable/exists.rb +2 -2
- data/lib/mongoid/matchable/gt.rb +4 -2
- data/lib/mongoid/matchable/gte.rb +4 -2
- data/lib/mongoid/matchable/in.rb +2 -2
- data/lib/mongoid/matchable/lt.rb +4 -2
- data/lib/mongoid/matchable/lte.rb +4 -2
- data/lib/mongoid/matchable/ne.rb +2 -2
- data/lib/mongoid/matchable/nin.rb +2 -2
- data/lib/mongoid/matchable/nor.rb +37 -0
- data/lib/mongoid/matchable/or.rb +3 -3
- data/lib/mongoid/matchable/regexp.rb +3 -3
- data/lib/mongoid/matchable/size.rb +2 -2
- data/lib/mongoid/matchable.rb +16 -7
- data/lib/mongoid/persistable/creatable.rb +5 -3
- data/lib/mongoid/persistable/deletable.rb +5 -3
- data/lib/mongoid/persistable/destroyable.rb +1 -5
- data/lib/mongoid/persistable/settable.rb +5 -5
- data/lib/mongoid/persistable/updatable.rb +7 -14
- data/lib/mongoid/persistable/upsertable.rb +2 -1
- data/lib/mongoid/persistable.rb +4 -6
- data/lib/mongoid/persistence_context.rb +220 -0
- data/lib/mongoid/query_cache.rb +67 -23
- data/lib/mongoid/railtie.rb +17 -1
- data/lib/mongoid/railties/controller_runtime.rb +86 -0
- data/lib/mongoid/relations/accessors.rb +3 -0
- data/lib/mongoid/relations/auto_save.rb +12 -4
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
- data/lib/mongoid/relations/counter_cache.rb +15 -5
- data/lib/mongoid/relations/eager/base.rb +3 -3
- data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
- data/lib/mongoid/relations/eager/has_many.rb +1 -1
- data/lib/mongoid/relations/eager.rb +6 -11
- data/lib/mongoid/relations/embedded/batchable.rb +20 -18
- data/lib/mongoid/relations/embedded/in.rb +13 -1
- data/lib/mongoid/relations/embedded/many.rb +51 -10
- data/lib/mongoid/relations/embedded/one.rb +14 -1
- data/lib/mongoid/relations/macros.rb +9 -1
- data/lib/mongoid/relations/many.rb +4 -0
- data/lib/mongoid/relations/metadata.rb +3 -3
- data/lib/mongoid/relations/options.rb +2 -2
- data/lib/mongoid/relations/proxy.rb +1 -31
- data/lib/mongoid/relations/referenced/in.rb +19 -10
- data/lib/mongoid/relations/referenced/many.rb +30 -26
- data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
- data/lib/mongoid/relations/referenced/one.rb +15 -1
- data/lib/mongoid/relations/synchronization.rb +12 -12
- data/lib/mongoid/relations/targets/enumerable.rb +24 -4
- data/lib/mongoid/relations/touchable.rb +7 -4
- data/lib/mongoid/reloadable.rb +2 -2
- data/lib/mongoid/scopable.rb +3 -3
- data/lib/mongoid/serializable.rb +1 -1
- data/lib/mongoid/stateful.rb +1 -0
- data/lib/mongoid/tasks/database.rb +3 -2
- data/lib/mongoid/threaded.rb +74 -0
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/validatable/uniqueness.rb +1 -2
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid.rb +6 -6
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +18 -3
- data/spec/app/models/agent.rb +2 -0
- data/spec/app/models/album.rb +5 -1
- data/spec/app/models/array_field.rb +7 -0
- data/spec/app/models/artist.rb +21 -0
- data/spec/app/models/band.rb +3 -0
- data/spec/app/models/book.rb +2 -1
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/app/models/dokument.rb +1 -0
- data/spec/app/models/ordered_post.rb +5 -0
- data/spec/app/models/oscar.rb +1 -2
- data/spec/app/models/page.rb +1 -1
- data/spec/app/models/person.rb +3 -3
- data/spec/app/models/princess.rb +2 -0
- data/spec/app/models/record.rb +1 -0
- data/spec/app/models/subscription.rb +1 -0
- data/spec/app/models/thing.rb +1 -1
- data/spec/config/mongoid.yml +15 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +3 -3
- data/spec/mongoid/atomic_spec.rb +5 -5
- data/spec/mongoid/attributes/nested_spec.rb +18 -14
- data/spec/mongoid/attributes/readonly_spec.rb +87 -44
- data/spec/mongoid/attributes_spec.rb +90 -5
- data/spec/mongoid/cacheable_spec.rb +112 -0
- data/spec/mongoid/changeable_spec.rb +58 -0
- data/spec/mongoid/clients/factory_spec.rb +80 -28
- data/spec/mongoid/clients/options_spec.rb +396 -95
- data/spec/mongoid/clients/sessions_spec.rb +334 -0
- data/spec/mongoid/clients_spec.rb +243 -101
- data/spec/mongoid/composable_spec.rb +7 -0
- data/spec/mongoid/config_spec.rb +67 -11
- data/spec/mongoid/contextual/atomic_spec.rb +3 -3
- data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
- data/spec/mongoid/contextual/mongo_spec.rb +275 -22
- data/spec/mongoid/contextual/none_spec.rb +15 -0
- data/spec/mongoid/copyable_spec.rb +13 -4
- data/spec/mongoid/criteria/modifiable_spec.rb +297 -16
- data/spec/mongoid/criteria/options_spec.rb +29 -0
- data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
- data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
- data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
- data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
- data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
- data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
- data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
- data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
- data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
- data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
- data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
- data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
- data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
- data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
- data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +4242 -0
- data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
- data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
- data/spec/mongoid/criteria/scopable_spec.rb +81 -0
- data/spec/mongoid/criteria_spec.rb +156 -22
- data/spec/mongoid/document_spec.rb +100 -90
- data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
- data/spec/mongoid/extensions/big_decimal_spec.rb +321 -19
- data/spec/mongoid/extensions/boolean_spec.rb +14 -0
- data/spec/mongoid/extensions/date_spec.rb +2 -6
- data/spec/mongoid/extensions/date_time_spec.rb +2 -6
- data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
- data/spec/mongoid/extensions/float_spec.rb +8 -1
- data/spec/mongoid/extensions/hash_spec.rb +15 -0
- data/spec/mongoid/extensions/integer_spec.rb +8 -1
- data/spec/mongoid/extensions/object_spec.rb +11 -0
- data/spec/mongoid/extensions/regexp_spec.rb +23 -0
- data/spec/mongoid/extensions/string_spec.rb +53 -4
- data/spec/mongoid/extensions/time_spec.rb +2 -6
- data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
- data/spec/mongoid/factory_spec.rb +11 -0
- data/spec/mongoid/fields_spec.rb +1 -1
- data/spec/mongoid/findable_spec.rb +47 -2
- data/spec/mongoid/indexable_spec.rb +15 -3
- data/spec/mongoid/interceptable_spec.rb +85 -19
- data/spec/mongoid/matchable/all_spec.rb +4 -4
- data/spec/mongoid/matchable/and_spec.rb +10 -10
- data/spec/mongoid/matchable/default_spec.rb +12 -12
- data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
- data/spec/mongoid/matchable/exists_spec.rb +5 -5
- data/spec/mongoid/matchable/gt_spec.rb +18 -7
- data/spec/mongoid/matchable/gte_spec.rb +17 -7
- data/spec/mongoid/matchable/in_spec.rb +5 -5
- data/spec/mongoid/matchable/lt_spec.rb +18 -7
- data/spec/mongoid/matchable/lte_spec.rb +18 -7
- data/spec/mongoid/matchable/ne_spec.rb +5 -5
- data/spec/mongoid/matchable/nin_spec.rb +5 -5
- data/spec/mongoid/matchable/nor_spec.rb +209 -0
- data/spec/mongoid/matchable/or_spec.rb +7 -7
- data/spec/mongoid/matchable/regexp_spec.rb +5 -5
- data/spec/mongoid/matchable/size_spec.rb +3 -3
- data/spec/mongoid/matchable_spec.rb +199 -54
- data/spec/mongoid/persistable/creatable_spec.rb +7 -2
- data/spec/mongoid/persistable/deletable_spec.rb +35 -1
- data/spec/mongoid/persistable/destroyable_spec.rb +25 -2
- data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
- data/spec/mongoid/persistable/savable_spec.rb +34 -29
- data/spec/mongoid/persistable/settable_spec.rb +77 -27
- data/spec/mongoid/persistable/updatable_spec.rb +182 -3
- data/spec/mongoid/persistable_spec.rb +16 -16
- data/spec/mongoid/persistence_context_spec.rb +694 -0
- data/spec/mongoid/positional_spec.rb +1 -1
- data/spec/mongoid/query_cache_spec.rb +170 -12
- data/spec/mongoid/relations/accessors_spec.rb +1 -1
- data/spec/mongoid/relations/auto_save_spec.rb +39 -6
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
- data/spec/mongoid/relations/builders_spec.rb +37 -10
- data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
- data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
- data/spec/mongoid/relations/eager_spec.rb +40 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +305 -59
- data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
- data/spec/mongoid/relations/macros_spec.rb +415 -7
- data/spec/mongoid/relations/metadata_spec.rb +15 -1
- data/spec/mongoid/relations/proxy_spec.rb +27 -1
- data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
- data/spec/mongoid/relations/referenced/many_spec.rb +35 -25
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
- data/spec/mongoid/relations/synchronization_spec.rb +48 -2
- data/spec/mongoid/relations/targets/enumerable_spec.rb +108 -0
- data/spec/mongoid/relations/touchable_spec.rb +40 -0
- data/spec/mongoid/reloadable_spec.rb +51 -0
- data/spec/mongoid/scopable_spec.rb +13 -0
- data/spec/mongoid/serializable_spec.rb +0 -50
- data/spec/mongoid/threaded_spec.rb +68 -0
- data/spec/mongoid/validatable/presence_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
- data/spec/mongoid/validatable_spec.rb +16 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
- data/spec/spec_helper.rb +101 -8
- data/spec/support/cluster_config.rb +158 -0
- data/spec/support/constraints.rb +101 -0
- data/spec/support/macros.rb +20 -0
- data/spec/support/session_registry.rb +50 -0
- data/spec/support/spec_config.rb +42 -0
- data.tar.gz.sig +0 -0
- metadata +163 -61
- metadata.gz.sig +0 -0
- data/lib/mongoid/clients/thread_options.rb +0 -19
- data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
- data/lib/mongoid/railties/document.rb +0 -12
- data/spec/mongoid/railties/document_spec.rb +0 -24
data/lib/mongoid/composable.rb
CHANGED
@@ -12,6 +12,7 @@ require "mongoid/scopable"
|
|
12
12
|
require "mongoid/serializable"
|
13
13
|
require "mongoid/shardable"
|
14
14
|
require "mongoid/stateful"
|
15
|
+
require "mongoid/cacheable"
|
15
16
|
require "mongoid/traversable"
|
16
17
|
require "mongoid/validatable"
|
17
18
|
|
@@ -32,7 +33,6 @@ module Mongoid
|
|
32
33
|
include ActiveModel::Model
|
33
34
|
include ActiveModel::ForbiddenAttributesProtection
|
34
35
|
include ActiveModel::Serializers::JSON
|
35
|
-
include ActiveModel::Serializers::Xml
|
36
36
|
include Atomic
|
37
37
|
include Changeable
|
38
38
|
include Clients
|
@@ -50,6 +50,7 @@ module Mongoid
|
|
50
50
|
include Serializable
|
51
51
|
include Shardable
|
52
52
|
include Stateful
|
53
|
+
include Cacheable
|
53
54
|
include Threaded::Lifecycle
|
54
55
|
include Traversable
|
55
56
|
include Validatable
|
@@ -74,16 +75,42 @@ module Mongoid
|
|
74
75
|
Scopable,
|
75
76
|
Serializable,
|
76
77
|
Clients,
|
78
|
+
Clients::Options,
|
77
79
|
Shardable,
|
78
80
|
Stateful,
|
81
|
+
Cacheable,
|
79
82
|
Threaded::Lifecycle,
|
80
83
|
Traversable,
|
81
84
|
Validatable,
|
82
85
|
Equality,
|
86
|
+
Relations::Synchronization,
|
87
|
+
Relations::Macros,
|
83
88
|
ActiveModel::Model,
|
84
89
|
ActiveModel::Validations
|
85
90
|
]
|
86
91
|
|
92
|
+
# These are methods names defined in included blocks that may conflict
|
93
|
+
# with user-defined relation or field names.
|
94
|
+
# They won't be in the list of Module.instance_methods on which the
|
95
|
+
# #prohibited_methods code below is dependent so we must track them
|
96
|
+
# separately.
|
97
|
+
#
|
98
|
+
# @return [ Array<Symbol> ] A list of reserved method names.
|
99
|
+
#
|
100
|
+
# @since 6.0.0
|
101
|
+
RESERVED_METHOD_NAMES = [ :fields,
|
102
|
+
:aliased_fields,
|
103
|
+
:localized_fields,
|
104
|
+
:index_specifications,
|
105
|
+
:shard_key_fields,
|
106
|
+
:nested_attributes,
|
107
|
+
:readonly_attributes,
|
108
|
+
:storage_options,
|
109
|
+
:cascades,
|
110
|
+
:cyclic,
|
111
|
+
:cache_timestamp_format
|
112
|
+
]
|
113
|
+
|
87
114
|
class << self
|
88
115
|
|
89
116
|
# Get a list of methods that would be a bad idea to define as field names
|
@@ -98,7 +125,7 @@ module Mongoid
|
|
98
125
|
def prohibited_methods
|
99
126
|
@prohibited_methods ||= MODULES.flat_map do |mod|
|
100
127
|
mod.instance_methods.map(&:to_sym)
|
101
|
-
end
|
128
|
+
end + RESERVED_METHOD_NAMES
|
102
129
|
end
|
103
130
|
end
|
104
131
|
end
|
data/lib/mongoid/config.rb
CHANGED
@@ -25,6 +25,7 @@ module Mongoid
|
|
25
25
|
option :use_activesupport_time_zone, default: true
|
26
26
|
option :use_utc, default: false
|
27
27
|
option :log_level, default: :info
|
28
|
+
option :belongs_to_required_by_default, default: true
|
28
29
|
option :app_name, default: nil
|
29
30
|
|
30
31
|
# Has Mongoid been configured? This is checking that at least a valid
|
@@ -23,7 +23,7 @@ module Mongoid
|
|
23
23
|
#
|
24
24
|
# @since 3.0.0
|
25
25
|
def aggregates(field)
|
26
|
-
result = collection.find.aggregate(pipeline(field)).to_a
|
26
|
+
result = collection.find.aggregate(pipeline(field), session: _session).to_a
|
27
27
|
if result.empty?
|
28
28
|
{ "count" => 0, "sum" => nil, "avg" => nil, "min" => nil, "max" => nil }
|
29
29
|
else
|
@@ -109,16 +109,16 @@ module Mongoid
|
|
109
109
|
# Perform an atomic $push/$each operation on the matching documents.
|
110
110
|
#
|
111
111
|
# @example Push the values to the matching docs.
|
112
|
-
# context.
|
112
|
+
# context.push_all(members: [ "Alan", "Fletch" ])
|
113
113
|
#
|
114
114
|
# @param [ Hash ] pushes The operations.
|
115
115
|
#
|
116
116
|
# @return [ nil ] Nil.
|
117
117
|
#
|
118
|
-
# @since
|
119
|
-
def
|
118
|
+
# @since 3.0.0
|
119
|
+
def push_all(pushes)
|
120
120
|
push_each_updates = collect_operations(pushes).each.inject({}) do |ops, (field, elements)|
|
121
|
-
ops.merge!(field => {
|
121
|
+
ops.merge!(field => {'$each' => elements})
|
122
122
|
end
|
123
123
|
view.update_many("$push" => push_each_updates)
|
124
124
|
end
|
@@ -165,13 +165,13 @@ module Mongoid
|
|
165
165
|
def raw
|
166
166
|
validate_out!
|
167
167
|
cmd = command
|
168
|
-
opts = { read: cmd.delete(:read)
|
169
|
-
@map_reduce.database.command(cmd, opts || {}).first
|
168
|
+
opts = { read: cmd.delete(:read) } if cmd[:read]
|
169
|
+
@map_reduce.database.command(cmd, (opts || {}).merge(session: _session)).first
|
170
170
|
end
|
171
171
|
alias :results :raw
|
172
172
|
|
173
173
|
# Execute the map/reduce, returning the raw output.
|
174
|
-
# Useful when you don't care about map/reduce's
|
174
|
+
# Useful when you don't care about map/reduce's output.
|
175
175
|
#
|
176
176
|
# @example Run the map reduce
|
177
177
|
# map_reduce.execute
|
@@ -249,6 +249,10 @@ module Mongoid
|
|
249
249
|
def validate_out!
|
250
250
|
raise Errors::NoMapReduceOutput.new({}) unless @map_reduce.out
|
251
251
|
end
|
252
|
+
|
253
|
+
def _session
|
254
|
+
criteria.send(:_session)
|
255
|
+
end
|
252
256
|
end
|
253
257
|
end
|
254
258
|
end
|
@@ -44,11 +44,12 @@ module Mongoid
|
|
44
44
|
deleted = count
|
45
45
|
removed = map do |doc|
|
46
46
|
prepare_remove(doc)
|
47
|
-
doc.
|
47
|
+
doc.send(:as_attributes)
|
48
48
|
end
|
49
49
|
unless removed.empty?
|
50
50
|
collection.find(selector).update_one(
|
51
|
-
positionally(selector, "$pullAll" => { path => removed })
|
51
|
+
positionally(selector, "$pullAll" => { path => removed }),
|
52
|
+
session: _session
|
52
53
|
)
|
53
54
|
end
|
54
55
|
deleted
|
@@ -148,7 +149,7 @@ module Mongoid
|
|
148
149
|
@documents = criteria.documents.select do |doc|
|
149
150
|
@root ||= doc._root
|
150
151
|
@collection ||= root.collection
|
151
|
-
doc.
|
152
|
+
doc._matches?(criteria.selector)
|
152
153
|
end
|
153
154
|
apply_sorting
|
154
155
|
apply_options
|
@@ -303,7 +304,7 @@ module Mongoid
|
|
303
304
|
updates["$set"].merge!(doc.atomic_updates["$set"] || {})
|
304
305
|
doc.move_changes
|
305
306
|
end
|
306
|
-
collection.find(selector).update_one(updates) unless updates["$set"].empty?
|
307
|
+
collection.find(selector).update_one(updates, session: _session) unless updates["$set"].empty?
|
307
308
|
end
|
308
309
|
|
309
310
|
# Get the limiting value.
|
@@ -444,6 +445,10 @@ module Mongoid
|
|
444
445
|
doc._parent.remove_child(doc)
|
445
446
|
doc.destroyed = true
|
446
447
|
end
|
448
|
+
|
449
|
+
def _session
|
450
|
+
@criteria.send(:_session)
|
451
|
+
end
|
447
452
|
end
|
448
453
|
end
|
449
454
|
end
|
@@ -24,6 +24,7 @@ module Mongoid
|
|
24
24
|
:sort,
|
25
25
|
:batch_size,
|
26
26
|
:max_scan,
|
27
|
+
:max_time_ms,
|
27
28
|
:snapshot,
|
28
29
|
:comment,
|
29
30
|
:read,
|
@@ -94,7 +95,8 @@ module Mongoid
|
|
94
95
|
def destroy
|
95
96
|
each.inject(0) do |count, doc|
|
96
97
|
doc.destroy
|
97
|
-
count += 1
|
98
|
+
count += 1 if acknowledged_write?
|
99
|
+
count
|
98
100
|
end
|
99
101
|
end
|
100
102
|
alias :destroy_all :destroy
|
@@ -110,7 +112,9 @@ module Mongoid
|
|
110
112
|
#
|
111
113
|
# @since 3.0.0
|
112
114
|
def distinct(field)
|
113
|
-
view.distinct(klass.database_field_name(field))
|
115
|
+
view.distinct(klass.database_field_name(field)).map do |value|
|
116
|
+
value.class.demongoize(value)
|
117
|
+
end
|
114
118
|
end
|
115
119
|
|
116
120
|
# Iterate over the context. If provided a block, yield to a Mongoid
|
@@ -233,21 +237,33 @@ module Mongoid
|
|
233
237
|
# @example Get the first document.
|
234
238
|
# context.first
|
235
239
|
#
|
236
|
-
# @note
|
237
|
-
#
|
238
|
-
#
|
239
|
-
#
|
240
|
-
#
|
240
|
+
# @note Automatically adding a sort on _id when no other sort is
|
241
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
242
|
+
# If you experience unexpected poor performance when using #first or #last
|
243
|
+
# and have no sort defined on the criteria, use the option { id_sort: :none }.
|
244
|
+
# Be aware that #first/#last won't guarantee order in this case.
|
245
|
+
#
|
246
|
+
# @param [ Hash ] opts The options for the query returning the first document.
|
247
|
+
#
|
248
|
+
# @option opts [ :none ] :id_sort Don't apply a sort on _id if no other sort
|
249
|
+
# is defined on the criteria.
|
241
250
|
#
|
242
251
|
# @return [ Document ] The first document.
|
243
252
|
#
|
244
253
|
# @since 3.0.0
|
245
|
-
def first
|
254
|
+
def first(opts = {})
|
246
255
|
return documents.first if cached? && cache_loaded?
|
247
256
|
try_cache(:first) do
|
248
|
-
if
|
249
|
-
|
250
|
-
|
257
|
+
if sort = view.sort || ({ _id: 1 } unless opts[:id_sort] == :none)
|
258
|
+
if raw_doc = view.sort(sort).limit(-1).first
|
259
|
+
doc = Factory.from_db(klass, raw_doc, criteria.options[:fields])
|
260
|
+
eager_load([doc]).first
|
261
|
+
end
|
262
|
+
else
|
263
|
+
if raw_doc = view.limit(-1).first
|
264
|
+
doc = Factory.from_db(klass, raw_doc, criteria.options[:fields])
|
265
|
+
eager_load([doc]).first
|
266
|
+
end
|
251
267
|
end
|
252
268
|
end
|
253
269
|
end
|
@@ -323,9 +339,9 @@ module Mongoid
|
|
323
339
|
# @since 3.0.0
|
324
340
|
def initialize(criteria)
|
325
341
|
@criteria, @klass, @cache = criteria, criteria.klass, criteria.options[:cache]
|
326
|
-
@collection = @klass.
|
342
|
+
@collection = @klass.collection
|
327
343
|
criteria.send(:merge_type_selection)
|
328
|
-
@view = collection.find(criteria.selector)
|
344
|
+
@view = collection.find(criteria.selector, session: _session)
|
329
345
|
apply_options
|
330
346
|
end
|
331
347
|
|
@@ -336,18 +352,21 @@ module Mongoid
|
|
336
352
|
# @example Get the last document.
|
337
353
|
# context.last
|
338
354
|
#
|
339
|
-
# @note
|
340
|
-
#
|
341
|
-
#
|
342
|
-
#
|
343
|
-
#
|
355
|
+
# @note Automatically adding a sort on _id when no other sort is
|
356
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
357
|
+
# If you experience unexpected poor performance when using #first or #last
|
358
|
+
# and have no sort defined on the criteria, use the option { id_sort: :none }.
|
359
|
+
# Be aware that #first/#last won't guarantee order in this case.
|
360
|
+
#
|
361
|
+
# @param [ Hash ] opts The options for the query returning the first document.
|
344
362
|
#
|
345
|
-
# @
|
363
|
+
# @option opts [ :none ] :id_sort Don't apply a sort on _id if no other sort
|
364
|
+
# is defined on the criteria.
|
346
365
|
#
|
347
366
|
# @since 3.0.0
|
348
|
-
def last
|
367
|
+
def last(opts = {})
|
349
368
|
try_cache(:last) do
|
350
|
-
with_inverse_sorting do
|
369
|
+
with_inverse_sorting(opts) do
|
351
370
|
if raw_doc = view.limit(-1).first
|
352
371
|
doc = Factory.from_db(klass, raw_doc, criteria.options[:fields])
|
353
372
|
eager_load([doc]).first
|
@@ -468,12 +487,16 @@ module Mongoid
|
|
468
487
|
# context.update({ "$set" => { name: "Smiths" }})
|
469
488
|
#
|
470
489
|
# @param [ Hash ] attributes The new attributes for the document.
|
490
|
+
# @param [ Hash ] opts The update operation options.
|
491
|
+
#
|
492
|
+
# @option opts [ Array ] :array_filters A set of filters specifying to which array elements
|
493
|
+
# an update should apply.
|
471
494
|
#
|
472
495
|
# @return [ nil, false ] False if no attributes were provided.
|
473
496
|
#
|
474
497
|
# @since 3.0.0
|
475
|
-
def update(attributes = nil)
|
476
|
-
update_documents(attributes)
|
498
|
+
def update(attributes = nil, opts = {})
|
499
|
+
update_documents(attributes, :update_one, opts)
|
477
500
|
end
|
478
501
|
|
479
502
|
# Update all the matching documents atomically.
|
@@ -482,12 +505,16 @@ module Mongoid
|
|
482
505
|
# context.update_all({ "$set" => { name: "Smiths" }})
|
483
506
|
#
|
484
507
|
# @param [ Hash ] attributes The new attributes for each document.
|
508
|
+
# @param [ Hash ] opts The update operation options.
|
509
|
+
#
|
510
|
+
# @option opts [ Array ] :array_filters A set of filters specifying to which array elements
|
511
|
+
# an update should apply.
|
485
512
|
#
|
486
513
|
# @return [ nil, false ] False if no attributes were provided.
|
487
514
|
#
|
488
515
|
# @since 3.0.0
|
489
|
-
def update_all(attributes = nil)
|
490
|
-
update_documents(attributes, :update_many)
|
516
|
+
def update_all(attributes = nil, opts = {})
|
517
|
+
update_documents(attributes, :update_many, opts)
|
491
518
|
end
|
492
519
|
|
493
520
|
private
|
@@ -523,10 +550,10 @@ module Mongoid
|
|
523
550
|
# @return [ true, false ] If the update succeeded.
|
524
551
|
#
|
525
552
|
# @since 3.0.4
|
526
|
-
def update_documents(attributes, method = :update_one)
|
553
|
+
def update_documents(attributes, method = :update_one, opts = {})
|
527
554
|
return false unless attributes
|
528
555
|
attributes = Hash[attributes.map { |k, v| [klass.database_field_name(k.to_s), v] }]
|
529
|
-
view.send(method, attributes.__consolidate__(klass))
|
556
|
+
view.send(method, attributes.__consolidate__(klass), opts)
|
530
557
|
end
|
531
558
|
|
532
559
|
# Apply the field limitations.
|
@@ -583,10 +610,10 @@ module Mongoid
|
|
583
610
|
# context.with_inverse_sorting
|
584
611
|
#
|
585
612
|
# @since 3.0.0
|
586
|
-
def with_inverse_sorting
|
613
|
+
def with_inverse_sorting(opts = {})
|
587
614
|
begin
|
588
|
-
if
|
589
|
-
@view = view.sort(Hash[
|
615
|
+
if sort = criteria.options[:sort] || ( { _id: 1 } unless opts[:id_sort] == :none )
|
616
|
+
@view = view.sort(Hash[sort.map{|k, v| [k, -1*v]}])
|
590
617
|
end
|
591
618
|
yield
|
592
619
|
ensure
|
@@ -678,6 +705,14 @@ module Mongoid
|
|
678
705
|
yield(doc)
|
679
706
|
documents.push(doc) if cacheable?
|
680
707
|
end
|
708
|
+
|
709
|
+
def _session
|
710
|
+
@criteria.send(:_session)
|
711
|
+
end
|
712
|
+
|
713
|
+
def acknowledged_write?
|
714
|
+
collection.write_concern.nil? || collection.write_concern.acknowledged?
|
715
|
+
end
|
681
716
|
end
|
682
717
|
end
|
683
718
|
end
|
@@ -21,6 +21,18 @@ module Mongoid
|
|
21
21
|
other.is_a?(None)
|
22
22
|
end
|
23
23
|
|
24
|
+
# Allow distinct for null context.
|
25
|
+
#
|
26
|
+
# @example Get the distinct values.
|
27
|
+
# context.distinct(:name)
|
28
|
+
#
|
29
|
+
# @param [ String, Symbol ] field the name of the field.
|
30
|
+
#
|
31
|
+
# @return [ Array ] Empty Array
|
32
|
+
def distinct(field)
|
33
|
+
[]
|
34
|
+
end
|
35
|
+
|
24
36
|
# Iterate over the null context. There are no documents to iterate over
|
25
37
|
# in this case.
|
26
38
|
#
|
data/lib/mongoid/copyable.rb
CHANGED
@@ -20,11 +20,18 @@ module Mongoid
|
|
20
20
|
# _id and id field in the document would cause problems with Mongoid
|
21
21
|
# elsewhere.
|
22
22
|
attrs = clone_document.except("_id", "id")
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
dynamic_attrs = {}
|
24
|
+
attrs.reject! do |attr_name, value|
|
25
|
+
dynamic_attrs.merge!(attr_name => value) unless self.attribute_names.include?(attr_name)
|
26
|
+
end
|
27
|
+
self.class.new(attrs).tap do |object|
|
28
|
+
dynamic_attrs.each do |attr_name, value|
|
29
|
+
if object.respond_to?("#{attr_name}=")
|
30
|
+
object.send("#{attr_name}=", value)
|
31
|
+
else
|
32
|
+
object.attributes[attr_name] = value
|
33
|
+
end
|
34
|
+
end
|
28
35
|
end
|
29
36
|
end
|
30
37
|
alias :dup :clone
|
@@ -40,7 +47,7 @@ module Mongoid
|
|
40
47
|
#
|
41
48
|
# @since 3.0.22
|
42
49
|
def clone_document
|
43
|
-
attrs =
|
50
|
+
attrs = as_attributes.__deep_copy__
|
44
51
|
process_localized_attributes(self, attrs)
|
45
52
|
attrs
|
46
53
|
end
|
@@ -27,8 +27,8 @@ module Mongoid
|
|
27
27
|
def marshal_load(data)
|
28
28
|
@scoping_options, raw_selector, raw_options = data.pop(3)
|
29
29
|
@klass, @driver, @inclusions, @documents, @strategy, @negating = data
|
30
|
-
@selector = load_hash(
|
31
|
-
@options = load_hash(
|
30
|
+
@selector = load_hash(Queryable::Selector, raw_selector)
|
31
|
+
@options = load_hash(Queryable::Options, raw_options)
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
@@ -3,6 +3,10 @@ module Mongoid
|
|
3
3
|
class Criteria
|
4
4
|
module Modifiable
|
5
5
|
|
6
|
+
# @attribute [r] create_attrs Additional attributes to add to the Document upon creation.
|
7
|
+
# @api private
|
8
|
+
attr_reader :create_attrs
|
9
|
+
|
6
10
|
# Build a document given the selector and return it.
|
7
11
|
# Complex criteria, such as $in and $or operations will get ignored.
|
8
12
|
#
|
@@ -57,6 +61,9 @@ module Mongoid
|
|
57
61
|
|
58
62
|
# Define attributes with which new documents will be created.
|
59
63
|
#
|
64
|
+
# Note that if `find_or_create_by` is called after this in a method chain, the attributes in
|
65
|
+
# the query will override those from this method.
|
66
|
+
#
|
60
67
|
# @example Define attributes to be used when a new document is created.
|
61
68
|
# Person.create_with(job: 'Engineer').find_or_create_by(employer: 'MongoDB')
|
62
69
|
#
|
@@ -64,7 +71,9 @@ module Mongoid
|
|
64
71
|
#
|
65
72
|
# @since 5.1.0
|
66
73
|
def create_with(attrs = {})
|
67
|
-
|
74
|
+
tap do
|
75
|
+
(@create_attrs ||= {}).merge!(attrs)
|
76
|
+
end
|
68
77
|
end
|
69
78
|
|
70
79
|
# Find the first +Document+ given the conditions, or creates a new document
|
@@ -172,8 +181,9 @@ module Mongoid
|
|
172
181
|
#
|
173
182
|
# @since 3.0.0
|
174
183
|
def create_document(method, attrs = nil, &block)
|
175
|
-
|
176
|
-
|
184
|
+
attrs = (create_attrs || {}).merge(attrs || {})
|
185
|
+
attributes = selector.reduce(attrs) do |hash, (key, value)|
|
186
|
+
unless invalid_key?(hash, key) || invalid_embedded_doc?(value)
|
177
187
|
hash[key] = value
|
178
188
|
end
|
179
189
|
hash
|
@@ -216,6 +226,22 @@ module Mongoid
|
|
216
226
|
def first_or(method, attrs = {}, &block)
|
217
227
|
first || create_document(method, attrs, &block)
|
218
228
|
end
|
229
|
+
|
230
|
+
private
|
231
|
+
|
232
|
+
def invalid_key?(hash, key)
|
233
|
+
# @todo Change this to BSON::String::ILLEGAL_KEY when ruby driver 2.3.0 is
|
234
|
+
# released and mongoid is updated to depend on driver >= 2.3.0
|
235
|
+
key.to_s =~ Mongoid::Document::ILLEGAL_KEY || hash.key?(key.to_sym) || hash.key?(key)
|
236
|
+
end
|
237
|
+
|
238
|
+
def invalid_embedded_doc?(value)
|
239
|
+
# @todo Change this to BSON::String::ILLEGAL_KEY when ruby driver 2.3.0 is
|
240
|
+
# released and mongoid is updated to depend on driver >= 2.3.0
|
241
|
+
value.is_a?(Hash) && value.any? do |key, v|
|
242
|
+
key.to_s =~ Mongoid::Document::ILLEGAL_KEY || invalid_embedded_doc?(v)
|
243
|
+
end
|
244
|
+
end
|
219
245
|
end
|
220
246
|
end
|
221
247
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
class Criteria
|
4
|
+
|
5
|
+
# Module containing functionality for getting options on a Criteria object.
|
6
|
+
#
|
7
|
+
# @since 6.0.0
|
8
|
+
module Options
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def persistence_context
|
13
|
+
klass.persistence_context
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_persistence_context(options)
|
17
|
+
PersistenceContext.set(klass, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def clear_persistence_context(original_cluster)
|
21
|
+
PersistenceContext.clear(klass, original_cluster)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
class Criteria
|
4
|
+
module Queryable
|
5
|
+
|
6
|
+
# Provides a DSL around crafting aggregation framework commands.
|
7
|
+
#
|
8
|
+
# @since 2.0.0
|
9
|
+
module Aggregable
|
10
|
+
extend Macroable
|
11
|
+
|
12
|
+
# @attribute [r] pipeline The aggregation pipeline.
|
13
|
+
attr_reader :pipeline
|
14
|
+
|
15
|
+
# @attribute [rw] aggregating Flag for whether or not we are aggregating.
|
16
|
+
attr_writer :aggregating
|
17
|
+
|
18
|
+
# Has the aggregable enter an aggregation state. Ie, are only aggregation
|
19
|
+
# operations allowed at this point on.
|
20
|
+
#
|
21
|
+
# @example Is the aggregable aggregating?
|
22
|
+
# aggregable.aggregating?
|
23
|
+
#
|
24
|
+
# @return [ true, false ] If the aggregable is aggregating.
|
25
|
+
#
|
26
|
+
# @since 2.0.0
|
27
|
+
def aggregating?
|
28
|
+
!!@aggregating
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add a group ($group) operation to the aggregation pipeline.
|
32
|
+
#
|
33
|
+
# @example Add a group operation being verbose.
|
34
|
+
# aggregable.group(count: { "$sum" => 1 }, max: { "$max" => "likes" })
|
35
|
+
#
|
36
|
+
# @example Add a group operation using symbol shortcuts.
|
37
|
+
# aggregable.group(:count.sum => 1, :max.max => "likes")
|
38
|
+
#
|
39
|
+
# @param [ Hash ] operation The group operation.
|
40
|
+
#
|
41
|
+
# @return [ Aggregable ] The aggregable.
|
42
|
+
#
|
43
|
+
# @since 2.0.0
|
44
|
+
def group(operation)
|
45
|
+
aggregation(operation) do |pipeline|
|
46
|
+
pipeline.group(operation)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
key :avg, :override, "$avg"
|
50
|
+
key :max, :override, "$max"
|
51
|
+
key :min, :override, "$min"
|
52
|
+
key :sum, :override, "$sum"
|
53
|
+
key :last, :override, "$last"
|
54
|
+
key :push, :override, "$push"
|
55
|
+
key :first, :override, "$first"
|
56
|
+
key :add_to_set, :override, "$addToSet"
|
57
|
+
|
58
|
+
# Add a projection ($project) to the aggregation pipeline.
|
59
|
+
#
|
60
|
+
# @example Add a projection to the pipeline.
|
61
|
+
# aggregable.project(author: 1, name: 0)
|
62
|
+
#
|
63
|
+
# @param [ Hash ] operation The projection to make.
|
64
|
+
#
|
65
|
+
# @return [ Aggregable ] The aggregable.
|
66
|
+
#
|
67
|
+
# @since 2.0.0
|
68
|
+
def project(operation = nil)
|
69
|
+
aggregation(operation) do |pipeline|
|
70
|
+
pipeline.project(operation)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Add an unwind ($unwind) to the aggregation pipeline.
|
75
|
+
#
|
76
|
+
# @example Add an unwind to the pipeline.
|
77
|
+
# aggregable.unwind(:field)
|
78
|
+
#
|
79
|
+
# @param [ String, Symbol ] field The name of the field to unwind.
|
80
|
+
#
|
81
|
+
# @return [ Aggregable ] The aggregable.
|
82
|
+
#
|
83
|
+
# @since 2.0.0
|
84
|
+
def unwind(field)
|
85
|
+
aggregation(field) do |pipeline|
|
86
|
+
pipeline.unwind(field)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# Add the aggregation operation.
|
93
|
+
#
|
94
|
+
# @api private
|
95
|
+
#
|
96
|
+
# @example Aggregate on the operation.
|
97
|
+
# aggregation(operation) do |pipeline|
|
98
|
+
# pipeline.push("$project" => operation)
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# @param [ Hash ] operation The operation for the pipeline.
|
102
|
+
#
|
103
|
+
# @return [ Aggregable ] The cloned aggregable.
|
104
|
+
#
|
105
|
+
# @since 2.0.0
|
106
|
+
def aggregation(operation)
|
107
|
+
return self unless operation
|
108
|
+
clone.tap do |query|
|
109
|
+
unless aggregating?
|
110
|
+
query.pipeline.concat(query.selector.to_pipeline)
|
111
|
+
query.pipeline.concat(query.options.to_pipeline)
|
112
|
+
query.aggregating = true
|
113
|
+
end
|
114
|
+
yield(query.pipeline)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|