mongoid 2.4.10 → 3.0.0.rc
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.
- data/CHANGELOG.md +843 -9
- data/LICENSE +1 -1
- data/README.md +10 -11
- data/Rakefile +2 -17
- data/lib/config/locales/en.yml +441 -51
- data/lib/mongoid/atomic/modifiers.rb +2 -2
- data/lib/mongoid/atomic/paths/embedded/many.rb +6 -6
- data/lib/mongoid/atomic/paths/embedded/one.rb +5 -5
- data/lib/mongoid/atomic/paths/embedded.rb +4 -5
- data/lib/mongoid/atomic/paths/root.rb +4 -5
- data/lib/mongoid/atomic.rb +16 -9
- data/lib/mongoid/attributes/processing.rb +14 -10
- data/lib/mongoid/attributes/readonly.rb +56 -0
- data/lib/mongoid/attributes.rb +95 -32
- data/lib/mongoid/callbacks.rb +100 -42
- data/lib/mongoid/collections/retry.rb +2 -3
- data/lib/mongoid/components.rb +10 -22
- data/lib/mongoid/config/environment.rb +4 -3
- data/lib/mongoid/config/inflections.rb +6 -0
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/config/validators/option.rb +25 -0
- data/lib/mongoid/config/validators/session.rb +140 -0
- data/lib/mongoid/config/validators.rb +3 -0
- data/lib/mongoid/config.rb +87 -233
- data/lib/mongoid/contextual/aggregable/memory.rb +98 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
- data/lib/mongoid/contextual/atomic.rb +179 -0
- data/lib/mongoid/contextual/command.rb +43 -0
- data/lib/mongoid/contextual/find_and_modify.rb +66 -0
- data/lib/mongoid/contextual/map_reduce.rb +273 -0
- data/lib/mongoid/contextual/memory.rb +383 -0
- data/lib/mongoid/contextual/mongo.rb +543 -0
- data/lib/mongoid/contextual.rb +50 -0
- data/lib/mongoid/copyable.rb +2 -2
- data/lib/mongoid/criteria.rb +436 -248
- data/lib/mongoid/criterion/inspection.rb +14 -8
- data/lib/mongoid/criterion/scoping.rb +114 -44
- data/lib/mongoid/dirty.rb +152 -67
- data/lib/mongoid/document.rb +68 -49
- data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
- data/lib/mongoid/errors/callback.rb +5 -6
- data/lib/mongoid/errors/delete_restriction.rb +29 -0
- data/lib/mongoid/errors/document_not_found.rb +98 -17
- data/lib/mongoid/errors/eager_load.rb +3 -6
- data/lib/mongoid/errors/invalid_collection.rb +3 -3
- data/lib/mongoid/errors/invalid_config_option.rb +27 -0
- data/lib/mongoid/errors/invalid_database.rb +3 -3
- data/lib/mongoid/errors/invalid_field.rb +54 -8
- data/lib/mongoid/errors/invalid_field_option.rb +35 -0
- data/lib/mongoid/errors/invalid_find.rb +3 -3
- data/lib/mongoid/errors/invalid_index.rb +28 -0
- data/lib/mongoid/errors/invalid_options.rb +4 -4
- data/lib/mongoid/errors/invalid_scope.rb +24 -0
- data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
- data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
- data/lib/mongoid/errors/invalid_time.rb +3 -6
- data/lib/mongoid/errors/inverse_not_found.rb +29 -0
- data/lib/mongoid/errors/mixed_relations.rb +4 -9
- data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
- data/lib/mongoid/errors/mongoid_error.rb +54 -3
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
- data/lib/mongoid/errors/no_default_session.rb +23 -0
- data/lib/mongoid/errors/no_environment.rb +3 -3
- data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
- data/lib/mongoid/errors/no_parent.rb +24 -0
- data/lib/mongoid/errors/no_session_config.rb +22 -0
- data/lib/mongoid/errors/no_session_database.rb +27 -0
- data/lib/mongoid/errors/no_session_hosts.rb +27 -0
- data/lib/mongoid/errors/no_sessions_config.rb +20 -0
- data/lib/mongoid/errors/readonly_attribute.rb +25 -0
- data/lib/mongoid/errors/scope_overwrite.rb +4 -4
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +4 -4
- data/lib/mongoid/errors/unknown_attribute.rb +25 -0
- data/lib/mongoid/errors/unsaved_document.rb +4 -8
- data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
- data/lib/mongoid/errors/unsupported_version.rb +4 -4
- data/lib/mongoid/errors/validations.rb +7 -6
- data/lib/mongoid/errors/versioning_not_on_root.rb +23 -0
- data/lib/mongoid/errors.rb +22 -1
- data/lib/mongoid/extensions/array.rb +127 -0
- data/lib/mongoid/extensions/big_decimal.rb +42 -0
- data/lib/mongoid/extensions/boolean.rb +24 -0
- data/lib/mongoid/extensions/date.rb +70 -0
- data/lib/mongoid/extensions/date_time.rb +68 -0
- data/lib/mongoid/extensions/false_class.rb +26 -0
- data/lib/mongoid/extensions/float.rb +44 -0
- data/lib/mongoid/extensions/hash.rb +91 -0
- data/lib/mongoid/extensions/integer.rb +54 -0
- data/lib/mongoid/extensions/module.rb +28 -0
- data/lib/mongoid/extensions/nil_class.rb +21 -0
- data/lib/mongoid/extensions/object.rb +188 -0
- data/lib/mongoid/extensions/object_id.rb +53 -0
- data/lib/mongoid/extensions/range.rb +55 -0
- data/lib/mongoid/extensions/regexp.rb +27 -0
- data/lib/mongoid/extensions/set.rb +55 -0
- data/lib/mongoid/extensions/string.rb +155 -0
- data/lib/mongoid/extensions/symbol.rb +54 -0
- data/lib/mongoid/extensions/time.rb +78 -0
- data/lib/mongoid/extensions/time_with_zone.rb +55 -0
- data/lib/mongoid/extensions/true_class.rb +26 -0
- data/lib/mongoid/extensions.rb +28 -76
- data/lib/mongoid/factory.rb +1 -1
- data/lib/mongoid/fields/foreign_key.rb +134 -0
- data/lib/mongoid/fields/localized.rb +73 -0
- data/lib/mongoid/fields/standard.rb +268 -0
- data/lib/mongoid/fields/validators/macro.rb +83 -0
- data/lib/mongoid/fields/validators.rb +2 -0
- data/lib/mongoid/fields.rb +129 -194
- data/lib/mongoid/finders.rb +42 -43
- data/lib/mongoid/hierarchy.rb +25 -14
- data/lib/mongoid/identity_map.rb +31 -19
- data/lib/mongoid/indexes/validators/options.rb +80 -0
- data/lib/mongoid/indexes.rb +66 -15
- data/lib/mongoid/inspection.rb +1 -1
- data/lib/mongoid/javascript.rb +1 -1
- data/lib/mongoid/json.rb +2 -2
- data/lib/mongoid/loggable.rb +69 -0
- data/lib/mongoid/matchers/all.rb +7 -8
- data/lib/mongoid/matchers/and.rb +3 -3
- data/lib/mongoid/matchers/default.rb +6 -4
- data/lib/mongoid/matchers/exists.rb +2 -2
- data/lib/mongoid/matchers/gt.rb +2 -2
- data/lib/mongoid/matchers/gte.rb +2 -2
- data/lib/mongoid/matchers/in.rb +3 -7
- data/lib/mongoid/matchers/lt.rb +2 -2
- data/lib/mongoid/matchers/lte.rb +2 -2
- data/lib/mongoid/matchers/ne.rb +2 -2
- data/lib/mongoid/matchers/nin.rb +2 -2
- data/lib/mongoid/matchers/or.rb +2 -2
- data/lib/mongoid/matchers/size.rb +2 -2
- data/lib/mongoid/matchers/strategies.rb +3 -3
- data/lib/mongoid/matchers.rb +1 -1
- data/lib/mongoid/multi_parameter_attributes.rb +8 -10
- data/lib/mongoid/nested_attributes.rb +17 -9
- data/lib/mongoid/observer.rb +1 -2
- data/lib/mongoid/paranoia.rb +13 -18
- data/lib/mongoid/persistence/atomic/add_to_set.rb +5 -9
- data/lib/mongoid/persistence/atomic/bit.rb +5 -7
- data/lib/mongoid/persistence/atomic/inc.rb +5 -7
- data/lib/mongoid/persistence/atomic/operation.rb +45 -6
- data/lib/mongoid/persistence/atomic/pop.rb +5 -7
- data/lib/mongoid/persistence/atomic/pull.rb +5 -7
- data/lib/mongoid/persistence/atomic/pull_all.rb +5 -7
- data/lib/mongoid/persistence/atomic/push.rb +4 -10
- data/lib/mongoid/persistence/atomic/push_all.rb +4 -10
- data/lib/mongoid/persistence/atomic/rename.rb +6 -7
- data/lib/mongoid/persistence/atomic/sets.rb +5 -7
- data/lib/mongoid/persistence/atomic/unset.rb +4 -5
- data/lib/mongoid/persistence/atomic.rb +2 -2
- data/lib/mongoid/persistence/deletion.rb +2 -2
- data/lib/mongoid/persistence/insertion.rb +10 -16
- data/lib/mongoid/persistence/modification.rb +5 -9
- data/lib/mongoid/persistence/operations/embedded/insert.rb +7 -6
- data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -5
- data/lib/mongoid/persistence/operations/insert.rb +4 -4
- data/lib/mongoid/persistence/operations/remove.rb +4 -4
- data/lib/mongoid/persistence/operations/update.rb +5 -5
- data/lib/mongoid/persistence/operations.rb +6 -19
- data/lib/mongoid/persistence.rb +64 -27
- data/lib/mongoid/railtie.rb +26 -11
- data/lib/mongoid/railties/database.rake +22 -108
- data/lib/mongoid/relations/accessors.rb +119 -19
- data/lib/mongoid/relations/auto_save.rb +59 -5
- data/lib/mongoid/relations/binding.rb +211 -2
- data/lib/mongoid/relations/bindings/embedded/in.rb +16 -22
- data/lib/mongoid/relations/bindings/embedded/many.rb +9 -50
- data/lib/mongoid/relations/bindings/embedded/one.rb +10 -16
- data/lib/mongoid/relations/bindings/referenced/in.rb +31 -57
- data/lib/mongoid/relations/bindings/referenced/many.rb +8 -20
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -19
- data/lib/mongoid/relations/bindings/referenced/one.rb +10 -24
- data/lib/mongoid/relations/builder.rb +3 -3
- data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
- data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
- data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -4
- data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
- data/lib/mongoid/relations/builders/referenced/many.rb +5 -5
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
- data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
- data/lib/mongoid/relations/builders.rb +19 -16
- data/lib/mongoid/relations/cascading/delete.rb +3 -5
- data/lib/mongoid/relations/cascading/destroy.rb +3 -3
- data/lib/mongoid/relations/cascading/nullify.rb +3 -3
- data/lib/mongoid/relations/cascading/restrict.rb +37 -0
- data/lib/mongoid/relations/cascading.rb +6 -4
- data/lib/mongoid/relations/constraint.rb +4 -3
- data/lib/mongoid/relations/conversions.rb +5 -6
- data/lib/mongoid/relations/cyclic.rb +7 -7
- data/lib/mongoid/relations/embedded/batchable.rb +346 -0
- data/lib/mongoid/relations/embedded/in.rb +23 -12
- data/lib/mongoid/relations/embedded/many.rb +99 -160
- data/lib/mongoid/relations/embedded/one.rb +25 -14
- data/lib/mongoid/relations/macros.rb +105 -60
- data/lib/mongoid/relations/many.rb +93 -14
- data/lib/mongoid/relations/metadata.rb +231 -45
- data/lib/mongoid/relations/nested_builder.rb +3 -5
- data/lib/mongoid/relations/one.rb +2 -2
- data/lib/mongoid/relations/options.rb +2 -2
- data/lib/mongoid/relations/polymorphic.rb +9 -9
- data/lib/mongoid/relations/proxy.rb +60 -31
- data/lib/mongoid/relations/referenced/in.rb +40 -15
- data/lib/mongoid/relations/referenced/many.rb +116 -128
- data/lib/mongoid/relations/referenced/many_to_many.rb +101 -46
- data/lib/mongoid/relations/referenced/one.rb +34 -13
- data/lib/mongoid/relations/reflections.rb +3 -3
- data/lib/mongoid/relations/synchronization.rb +19 -23
- data/lib/mongoid/relations/targets/enumerable.rb +86 -57
- data/lib/mongoid/relations/touchable.rb +32 -0
- data/lib/mongoid/relations.rb +6 -6
- data/lib/mongoid/reloading.rb +12 -14
- data/lib/mongoid/scoping.rb +329 -0
- data/lib/mongoid/serialization.rb +13 -30
- data/lib/mongoid/sessions/factory.rb +106 -0
- data/lib/mongoid/sessions/mongo_uri.rb +93 -0
- data/lib/mongoid/sessions/validators/storage.rb +49 -0
- data/lib/mongoid/sessions/validators.rb +2 -0
- data/lib/mongoid/sessions.rb +359 -0
- data/lib/mongoid/sharding.rb +6 -6
- data/lib/mongoid/state.rb +6 -7
- data/lib/mongoid/threaded/lifecycle.rb +21 -21
- data/lib/mongoid/threaded/sessions.rb +0 -0
- data/lib/mongoid/threaded.rb +167 -59
- data/lib/mongoid/timestamps/created.rb +8 -4
- data/lib/mongoid/timestamps/timeless.rb +6 -4
- data/lib/mongoid/timestamps/updated.rb +3 -3
- data/lib/mongoid/timestamps.rb +1 -1
- data/lib/mongoid/unit_of_work.rb +61 -0
- data/lib/mongoid/validations/associated.rb +2 -2
- data/lib/mongoid/validations/format.rb +2 -2
- data/lib/mongoid/validations/presence.rb +34 -4
- data/lib/mongoid/validations/uniqueness.rb +8 -10
- data/lib/mongoid/validations.rb +28 -20
- data/lib/mongoid/version.rb +2 -2
- data/lib/mongoid/versioning.rb +25 -26
- data/lib/mongoid.rb +24 -39
- data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
- data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +59 -19
- data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
- data/lib/rails/generators/mongoid_generator.rb +5 -5
- data/lib/rails/mongoid.rb +69 -25
- metadata +92 -154
- data/lib/config/locales/bg.yml +0 -61
- data/lib/config/locales/de.yml +0 -61
- data/lib/config/locales/en-GB.yml +0 -64
- data/lib/config/locales/es.yml +0 -59
- data/lib/config/locales/fr.yml +0 -62
- data/lib/config/locales/hi.yml +0 -53
- data/lib/config/locales/hu.yml +0 -64
- data/lib/config/locales/id.yml +0 -62
- data/lib/config/locales/it.yml +0 -59
- data/lib/config/locales/ja.yml +0 -57
- data/lib/config/locales/kr.yml +0 -54
- data/lib/config/locales/nl.yml +0 -61
- data/lib/config/locales/pl.yml +0 -59
- data/lib/config/locales/pt-BR.yml +0 -60
- data/lib/config/locales/pt.yml +0 -60
- data/lib/config/locales/ro.yml +0 -66
- data/lib/config/locales/ru.yml +0 -61
- data/lib/config/locales/sv.yml +0 -60
- data/lib/config/locales/vi.yml +0 -62
- data/lib/config/locales/zh-CN.yml +0 -53
- data/lib/mongoid/collection.rb +0 -157
- data/lib/mongoid/collections/master.rb +0 -45
- data/lib/mongoid/collections/operations.rb +0 -44
- data/lib/mongoid/collections.rb +0 -120
- data/lib/mongoid/config/database.rb +0 -181
- data/lib/mongoid/config/replset_database.rb +0 -80
- data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
- data/lib/mongoid/contexts/enumerable.rb +0 -313
- data/lib/mongoid/contexts/mongo.rb +0 -487
- data/lib/mongoid/contexts.rb +0 -25
- data/lib/mongoid/criterion/builder.rb +0 -34
- data/lib/mongoid/criterion/complex.rb +0 -84
- data/lib/mongoid/criterion/creational.rb +0 -34
- data/lib/mongoid/criterion/exclusion.rb +0 -108
- data/lib/mongoid/criterion/inclusion.rb +0 -290
- data/lib/mongoid/criterion/optional.rb +0 -259
- data/lib/mongoid/criterion/selector.rb +0 -177
- data/lib/mongoid/cursor.rb +0 -88
- data/lib/mongoid/default_scope.rb +0 -36
- data/lib/mongoid/errors/invalid_type.rb +0 -25
- data/lib/mongoid/extensions/array/deep_copy.rb +0 -25
- data/lib/mongoid/extensions/array/deletion.rb +0 -29
- data/lib/mongoid/extensions/false_class/equality.rb +0 -26
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +0 -47
- data/lib/mongoid/extensions/hash/deep_copy.rb +0 -25
- data/lib/mongoid/extensions/hash/scoping.rb +0 -25
- data/lib/mongoid/extensions/integer/checks.rb +0 -23
- data/lib/mongoid/extensions/nil/collectionization.rb +0 -23
- data/lib/mongoid/extensions/object/checks.rb +0 -29
- data/lib/mongoid/extensions/object/deep_copy.rb +0 -21
- data/lib/mongoid/extensions/object/reflections.rb +0 -48
- data/lib/mongoid/extensions/object/substitutable.rb +0 -15
- data/lib/mongoid/extensions/object/yoda.rb +0 -44
- data/lib/mongoid/extensions/object_id/conversions.rb +0 -60
- data/lib/mongoid/extensions/proc/scoping.rb +0 -25
- data/lib/mongoid/extensions/string/checks.rb +0 -36
- data/lib/mongoid/extensions/string/conversions.rb +0 -22
- data/lib/mongoid/extensions/string/inflections.rb +0 -118
- data/lib/mongoid/extensions/symbol/checks.rb +0 -23
- data/lib/mongoid/extensions/symbol/inflections.rb +0 -67
- data/lib/mongoid/extensions/true_class/equality.rb +0 -26
- data/lib/mongoid/extras.rb +0 -31
- data/lib/mongoid/fields/internal/array.rb +0 -76
- data/lib/mongoid/fields/internal/big_decimal.rb +0 -63
- data/lib/mongoid/fields/internal/bignum.rb +0 -10
- data/lib/mongoid/fields/internal/binary.rb +0 -11
- data/lib/mongoid/fields/internal/boolean.rb +0 -58
- data/lib/mongoid/fields/internal/date.rb +0 -51
- data/lib/mongoid/fields/internal/date_time.rb +0 -28
- data/lib/mongoid/fields/internal/false_class.rb +0 -10
- data/lib/mongoid/fields/internal/fixnum.rb +0 -10
- data/lib/mongoid/fields/internal/float.rb +0 -47
- data/lib/mongoid/fields/internal/foreign_keys/array.rb +0 -88
- data/lib/mongoid/fields/internal/foreign_keys/object.rb +0 -56
- data/lib/mongoid/fields/internal/hash.rb +0 -11
- data/lib/mongoid/fields/internal/integer.rb +0 -59
- data/lib/mongoid/fields/internal/localized.rb +0 -62
- data/lib/mongoid/fields/internal/nil_class.rb +0 -53
- data/lib/mongoid/fields/internal/object.rb +0 -11
- data/lib/mongoid/fields/internal/object_id.rb +0 -46
- data/lib/mongoid/fields/internal/range.rb +0 -61
- data/lib/mongoid/fields/internal/set.rb +0 -57
- data/lib/mongoid/fields/internal/string.rb +0 -42
- data/lib/mongoid/fields/internal/symbol.rb +0 -43
- data/lib/mongoid/fields/internal/time.rb +0 -23
- data/lib/mongoid/fields/internal/time_with_zone.rb +0 -23
- data/lib/mongoid/fields/internal/timekeeping.rb +0 -122
- data/lib/mongoid/fields/internal/true_class.rb +0 -10
- data/lib/mongoid/fields/mappings.rb +0 -42
- data/lib/mongoid/fields/serializable.rb +0 -270
- data/lib/mongoid/identity.rb +0 -92
- data/lib/mongoid/keys.rb +0 -144
- data/lib/mongoid/logger.rb +0 -45
- data/lib/mongoid/multi_database.rb +0 -36
- data/lib/mongoid/named_scope.rb +0 -166
- data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
- data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
- data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
- data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
- data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
- data/lib/mongoid/relations/embedded/atomic.rb +0 -89
- data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
- data/lib/mongoid/relations/referenced/batch.rb +0 -73
- data/lib/mongoid/safety.rb +0 -105
- data/lib/mongoid/scope.rb +0 -31
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Contextual
|
|
4
|
+
module Aggregable
|
|
5
|
+
# Contains behaviour for aggregating values in memory.
|
|
6
|
+
module Memory
|
|
7
|
+
|
|
8
|
+
# Get the average value of the provided field.
|
|
9
|
+
#
|
|
10
|
+
# @example Get the average of a single field.
|
|
11
|
+
# aggregable.avg(:likes)
|
|
12
|
+
#
|
|
13
|
+
# @param [ Symbol ] field The field to average.
|
|
14
|
+
#
|
|
15
|
+
# @return [ Float ] The average.
|
|
16
|
+
#
|
|
17
|
+
# @since 3.0.0
|
|
18
|
+
def avg(field)
|
|
19
|
+
count > 0 ? sum(field).to_f / count.to_f : nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Get the max value of the provided field. If provided a block, will
|
|
23
|
+
# return the Document with the greatest value for the field, in
|
|
24
|
+
# accordance with Ruby's enumerable API.
|
|
25
|
+
#
|
|
26
|
+
# @example Get the max of a single field.
|
|
27
|
+
# aggregable.max(:likes)
|
|
28
|
+
#
|
|
29
|
+
# @example Get the document with the max value.
|
|
30
|
+
# aggregable.max do |a, b|
|
|
31
|
+
# a.likes <=> b.likes
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
# @param [ Symbol ] field The field to max.
|
|
35
|
+
#
|
|
36
|
+
# @return [ Float, Document ] The max value or document with the max
|
|
37
|
+
# value.
|
|
38
|
+
#
|
|
39
|
+
# @since 3.0.0
|
|
40
|
+
def max(field = nil)
|
|
41
|
+
if block_given?
|
|
42
|
+
super()
|
|
43
|
+
else
|
|
44
|
+
count > 0 ? max_by { |doc| doc.send(field) }.send(field) : nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Get the min value of the provided field. If provided a block, will
|
|
49
|
+
# return the Document with the smallest value for the field, in
|
|
50
|
+
# accordance with Ruby's enumerable API.
|
|
51
|
+
#
|
|
52
|
+
# @example Get the min of a single field.
|
|
53
|
+
# aggregable.min(:likes)
|
|
54
|
+
#
|
|
55
|
+
# @example Get the document with the min value.
|
|
56
|
+
# aggregable.min do |a, b|
|
|
57
|
+
# a.likes <=> b.likes
|
|
58
|
+
# end
|
|
59
|
+
#
|
|
60
|
+
# @param [ Symbol ] field The field to min.
|
|
61
|
+
#
|
|
62
|
+
# @return [ Float, Document ] The min value or document with the min
|
|
63
|
+
# value.
|
|
64
|
+
#
|
|
65
|
+
# @since 3.0.0
|
|
66
|
+
def min(field = nil)
|
|
67
|
+
if block_given?
|
|
68
|
+
super()
|
|
69
|
+
else
|
|
70
|
+
count > 0 ? min_by { |doc| doc.send(field) }.send(field) : nil
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Get the sum value of the provided field. If provided a block, will
|
|
75
|
+
# return the sum in accordance with Ruby's enumerable API.
|
|
76
|
+
#
|
|
77
|
+
# @example Get the sum of a single field.
|
|
78
|
+
# aggregable.sum(:likes)
|
|
79
|
+
#
|
|
80
|
+
# @example Get the sum for the provided block.
|
|
81
|
+
# aggregable.sum(&:likes)
|
|
82
|
+
#
|
|
83
|
+
# @param [ Symbol ] field The field to sum.
|
|
84
|
+
#
|
|
85
|
+
# @return [ Float ] The sum value.
|
|
86
|
+
#
|
|
87
|
+
# @since 3.0.0
|
|
88
|
+
def sum(field = nil)
|
|
89
|
+
if block_given?
|
|
90
|
+
super()
|
|
91
|
+
else
|
|
92
|
+
count > 0 ? super(0) { |doc| doc.send(field) } : nil
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Contextual
|
|
4
|
+
module Aggregable
|
|
5
|
+
# Contains behaviour for aggregating values in Mongo.
|
|
6
|
+
module Mongo
|
|
7
|
+
|
|
8
|
+
# Get all the aggregate values for the provided field.
|
|
9
|
+
#
|
|
10
|
+
# @example Get all the aggregate values.
|
|
11
|
+
# aggregable.aggregates(:likes)
|
|
12
|
+
#
|
|
13
|
+
# @param [ String, Symbol ] field The field name.
|
|
14
|
+
#
|
|
15
|
+
# @return [ Hash ] The aggregate values in the form:
|
|
16
|
+
# {
|
|
17
|
+
# "count" => 2.0,
|
|
18
|
+
# "max" => 1000.0,
|
|
19
|
+
# "min" => 500.0,
|
|
20
|
+
# "sum" => 1500.0,
|
|
21
|
+
# "avg" => 750.0
|
|
22
|
+
# }
|
|
23
|
+
#
|
|
24
|
+
# @since 3.0.0
|
|
25
|
+
def aggregates(field)
|
|
26
|
+
if query.count > 0
|
|
27
|
+
map_reduce(mapper(field), reducer).
|
|
28
|
+
out(inline: 1).finalize(finalizer).first["value"]
|
|
29
|
+
else
|
|
30
|
+
{ "count" => 0 }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Get the average value of the provided field.
|
|
35
|
+
#
|
|
36
|
+
# @example Get the average of a single field.
|
|
37
|
+
# aggregable.avg(:likes)
|
|
38
|
+
#
|
|
39
|
+
# @param [ Symbol ] field The field to average.
|
|
40
|
+
#
|
|
41
|
+
# @return [ Float ] The average.
|
|
42
|
+
#
|
|
43
|
+
# @since 3.0.0
|
|
44
|
+
def avg(field)
|
|
45
|
+
aggregates(field)["avg"]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Get the max value of the provided field. If provided a block, will
|
|
49
|
+
# return the Document with the greatest value for the field, in
|
|
50
|
+
# accordance with Ruby's enumerable API.
|
|
51
|
+
#
|
|
52
|
+
# @example Get the max of a single field.
|
|
53
|
+
# aggregable.max(:likes)
|
|
54
|
+
#
|
|
55
|
+
# @example Get the document with the max value.
|
|
56
|
+
# aggregable.max do |a, b|
|
|
57
|
+
# a.likes <=> b.likes
|
|
58
|
+
# end
|
|
59
|
+
#
|
|
60
|
+
# @param [ Symbol ] field The field to max.
|
|
61
|
+
#
|
|
62
|
+
# @return [ Float, Document ] The max value or document with the max
|
|
63
|
+
# value.
|
|
64
|
+
#
|
|
65
|
+
# @since 3.0.0
|
|
66
|
+
def max(field = nil)
|
|
67
|
+
block_given? ? super() : aggregates(field)["max"]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Get the min value of the provided field. If provided a block, will
|
|
71
|
+
# return the Document with the smallest value for the field, in
|
|
72
|
+
# accordance with Ruby's enumerable API.
|
|
73
|
+
#
|
|
74
|
+
# @example Get the min of a single field.
|
|
75
|
+
# aggregable.min(:likes)
|
|
76
|
+
#
|
|
77
|
+
# @example Get the document with the min value.
|
|
78
|
+
# aggregable.min do |a, b|
|
|
79
|
+
# a.likes <=> b.likes
|
|
80
|
+
# end
|
|
81
|
+
#
|
|
82
|
+
# @param [ Symbol ] field The field to min.
|
|
83
|
+
#
|
|
84
|
+
# @return [ Float, Document ] The min value or document with the min
|
|
85
|
+
# value.
|
|
86
|
+
#
|
|
87
|
+
# @since 3.0.0
|
|
88
|
+
def min(field = nil)
|
|
89
|
+
block_given? ? super() : aggregates(field)["min"]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Get the sum value of the provided field. If provided a block, will
|
|
93
|
+
# return the sum in accordance with Ruby's enumerable API.
|
|
94
|
+
#
|
|
95
|
+
# @example Get the sum of a single field.
|
|
96
|
+
# aggregable.sum(:likes)
|
|
97
|
+
#
|
|
98
|
+
# @example Get the sum for the provided block.
|
|
99
|
+
# aggregable.sum(&:likes)
|
|
100
|
+
#
|
|
101
|
+
# @param [ Symbol ] field The field to sum.
|
|
102
|
+
#
|
|
103
|
+
# @return [ Float ] The sum value.
|
|
104
|
+
#
|
|
105
|
+
# @since 3.0.0
|
|
106
|
+
def sum(field = nil)
|
|
107
|
+
block_given? ? super() : aggregates(field)["sum"]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
private
|
|
111
|
+
|
|
112
|
+
# Get the finalize function.
|
|
113
|
+
#
|
|
114
|
+
# @api private
|
|
115
|
+
#
|
|
116
|
+
# @example Get the finalize function.
|
|
117
|
+
# aggregable.finalizer
|
|
118
|
+
#
|
|
119
|
+
# @return [ String ] The finalize JS function.
|
|
120
|
+
#
|
|
121
|
+
# @since 3.0.0
|
|
122
|
+
def finalizer
|
|
123
|
+
%Q{
|
|
124
|
+
function(key, agg) {
|
|
125
|
+
agg.avg = agg.sum / agg.count;
|
|
126
|
+
return agg;
|
|
127
|
+
}}
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Get the map function for the provided field.
|
|
131
|
+
#
|
|
132
|
+
# @api private
|
|
133
|
+
#
|
|
134
|
+
# @example Get the map function.
|
|
135
|
+
# aggregable.mapper(:likes)
|
|
136
|
+
#
|
|
137
|
+
# @param [ String, Symbol ] field The name of the field.
|
|
138
|
+
#
|
|
139
|
+
# @return [ String ] The map JS function.
|
|
140
|
+
#
|
|
141
|
+
# @since 3.0.0
|
|
142
|
+
def mapper(field)
|
|
143
|
+
%Q{
|
|
144
|
+
function() {
|
|
145
|
+
var agg = {
|
|
146
|
+
count: 1,
|
|
147
|
+
max: this.#{field},
|
|
148
|
+
min: this.#{field},
|
|
149
|
+
sum: this.#{field}
|
|
150
|
+
};
|
|
151
|
+
emit("#{field}", agg);
|
|
152
|
+
}}
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Get the reduce function for the provided field.
|
|
156
|
+
#
|
|
157
|
+
# @api private
|
|
158
|
+
#
|
|
159
|
+
# @example Get the reduce function.
|
|
160
|
+
# aggregable.reducer(:likes)
|
|
161
|
+
#
|
|
162
|
+
# @return [ String ] The reduce JS function.
|
|
163
|
+
#
|
|
164
|
+
# @since 3.0.0
|
|
165
|
+
def reducer
|
|
166
|
+
%Q{
|
|
167
|
+
function(key, values) {
|
|
168
|
+
var agg = { count: 0, max: null, min: null, sum: 0 };
|
|
169
|
+
values.forEach(function(val) {
|
|
170
|
+
if (agg.max == null || val.max > agg.max) agg.max = val.max;
|
|
171
|
+
if (agg.min == null || val.max < agg.min) agg.min = val.max;
|
|
172
|
+
agg.count += 1;
|
|
173
|
+
agg.sum += val.sum;
|
|
174
|
+
});
|
|
175
|
+
return agg;
|
|
176
|
+
}}
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Contextual
|
|
4
|
+
module Atomic
|
|
5
|
+
|
|
6
|
+
# Execute an atomic $addToSet on the matching documents.
|
|
7
|
+
#
|
|
8
|
+
# @example Add the value to the set.
|
|
9
|
+
# context.add_to_set(:members, "Dave")
|
|
10
|
+
#
|
|
11
|
+
# @param [ String, Symbol ] field The name of the field to add to.
|
|
12
|
+
# @param [ Object ] value The single value to add.
|
|
13
|
+
#
|
|
14
|
+
# @return [ nil ] Nil.
|
|
15
|
+
#
|
|
16
|
+
# @since 3.0.0
|
|
17
|
+
def add_to_set(field, value)
|
|
18
|
+
query.update_all("$addToSet" => { field => value })
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Perform an atomic $bit operation on the matching documents.
|
|
22
|
+
#
|
|
23
|
+
# @example Perform the bitwise op.
|
|
24
|
+
# context.bit(:likes, { and: 14, or: 4 })
|
|
25
|
+
#
|
|
26
|
+
# @param [ String, Symbol ] field The name of the field to operate on.
|
|
27
|
+
# @param [ Hash ] value The bitwise operations to perform. Keys may be
|
|
28
|
+
# "and" or "or" and must have numeric values.
|
|
29
|
+
#
|
|
30
|
+
# @return [ nil ] Nil.
|
|
31
|
+
#
|
|
32
|
+
# @since 3.0.0
|
|
33
|
+
def bit(field, value)
|
|
34
|
+
query.update_all("$bit" => { field => value })
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Perform an atomic $inc operation on the matching documents.
|
|
38
|
+
#
|
|
39
|
+
# @example Perform the atomic increment.
|
|
40
|
+
# context.inc(:likes, 10)
|
|
41
|
+
#
|
|
42
|
+
# @param [ String, Symbol ] field The field to increment.
|
|
43
|
+
# @param [ Integer ] value The amount to increment by.
|
|
44
|
+
#
|
|
45
|
+
# @return [ nil ] Nil.
|
|
46
|
+
#
|
|
47
|
+
# @since 3.0.0
|
|
48
|
+
def inc(field, value)
|
|
49
|
+
query.update_all("$inc" => { field => value })
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Perform an atomic $pop operation on the matching documents.
|
|
53
|
+
#
|
|
54
|
+
# @example Pop the first value on the matches.
|
|
55
|
+
# context.pop(:members, -1)
|
|
56
|
+
#
|
|
57
|
+
# @example Pop the last value on the matches.
|
|
58
|
+
# context.pop(:members, 1)
|
|
59
|
+
#
|
|
60
|
+
# @param [ String, Symbol ] field The name of the array field to pop
|
|
61
|
+
# from.
|
|
62
|
+
# @param [ Integer ] value 1 to pop from the end, -1 to pop from the
|
|
63
|
+
# front.
|
|
64
|
+
#
|
|
65
|
+
# @return [ nil ] Nil.
|
|
66
|
+
#
|
|
67
|
+
# @since 3.0.0
|
|
68
|
+
def pop(field, value)
|
|
69
|
+
query.update_all("$pop" => { field => value })
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Perform an atomic $pull operation on the matching documents.
|
|
73
|
+
#
|
|
74
|
+
# @example Pull the value from the matches.
|
|
75
|
+
# context.pull(:members, "Dave")
|
|
76
|
+
#
|
|
77
|
+
# @note Expression pulling is not yet supported.
|
|
78
|
+
#
|
|
79
|
+
# @param [ String, Symbol ] field The field to pull from.
|
|
80
|
+
# @param [ Object ] value The single value to pull.
|
|
81
|
+
#
|
|
82
|
+
# @return [ nil ] Nil.
|
|
83
|
+
#
|
|
84
|
+
# @since 3.0.0
|
|
85
|
+
def pull(field, value)
|
|
86
|
+
query.update_all("$pull" => { field => value })
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Perform an atomic $pullAll operation on the matching documents.
|
|
90
|
+
#
|
|
91
|
+
# @example Pull all the matching values from the matches.
|
|
92
|
+
# context.pull_all(:members, [ "Alan", "Vince" ])
|
|
93
|
+
#
|
|
94
|
+
# @param [ String, Symbol ] field The field to pull from.
|
|
95
|
+
# @param [ Array<Object> ] values The values to pull.
|
|
96
|
+
#
|
|
97
|
+
# @return [ nil ] Nil.
|
|
98
|
+
#
|
|
99
|
+
# @since 3.0.0
|
|
100
|
+
def pull_all(field, values)
|
|
101
|
+
query.update_all("$pullAll" => { field => values })
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Perform an atomic $push operation on the matching documents.
|
|
105
|
+
#
|
|
106
|
+
# @example Push the value to the matching docs.
|
|
107
|
+
# context.push(:members, "Alan")
|
|
108
|
+
#
|
|
109
|
+
# @param [ String, Symbol ] field The field to push to.
|
|
110
|
+
# @param [ Object ] value The value to push.
|
|
111
|
+
#
|
|
112
|
+
# @return [ nil ] Nil.
|
|
113
|
+
#
|
|
114
|
+
# @since 3.0.0
|
|
115
|
+
def push(field, value)
|
|
116
|
+
query.update_all("$push" => { field => value })
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Perform an atomic $pushAll operation on the matching documents.
|
|
120
|
+
#
|
|
121
|
+
# @example Push the values to the matching docs.
|
|
122
|
+
# context.push(:members, [ "Alan", "Fletch" ])
|
|
123
|
+
#
|
|
124
|
+
# @param [ String, Symbol ] field The field to push to.
|
|
125
|
+
# @param [ Array<Object> ] values The values to push.
|
|
126
|
+
#
|
|
127
|
+
# @return [ nil ] Nil.
|
|
128
|
+
#
|
|
129
|
+
# @since 3.0.0
|
|
130
|
+
def push_all(field, values)
|
|
131
|
+
query.update_all("$pushAll" => { field => values })
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Perform an atomic $rename of fields on the matching documents.
|
|
135
|
+
#
|
|
136
|
+
# @example Rename the fields on the matching documents.
|
|
137
|
+
# context.rename(:members, :artists)
|
|
138
|
+
#
|
|
139
|
+
# @param [ String, Symbol ] old_name The old field name.
|
|
140
|
+
# @param [ String, Symbol ] new_name The new field name.
|
|
141
|
+
#
|
|
142
|
+
# @return [ nil ] Nil.
|
|
143
|
+
#
|
|
144
|
+
# @since 3.0.0
|
|
145
|
+
def rename(old_name, new_name)
|
|
146
|
+
query.update_all("$rename" => { old_name.to_s => new_name.to_s })
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Perform an atomic $set of fields on the matching documents.
|
|
150
|
+
#
|
|
151
|
+
# @example Set the field value on the matches.
|
|
152
|
+
# context.set(:name, "Depeche Mode")
|
|
153
|
+
#
|
|
154
|
+
# @param [ String, Symbol ] field The name of the field.
|
|
155
|
+
# @param [ Object ] value The value to set.
|
|
156
|
+
#
|
|
157
|
+
# @return [ nil ] Nil.
|
|
158
|
+
#
|
|
159
|
+
# @since 3.0.0
|
|
160
|
+
def set(field, value)
|
|
161
|
+
query.update_all("$set" => { field => value })
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Perform an atomic $unset of a field on the matching documents.
|
|
165
|
+
#
|
|
166
|
+
# @example Unset the field on the matches.
|
|
167
|
+
# context.unset(:name)
|
|
168
|
+
#
|
|
169
|
+
# @param [ String, Symbol ] field The name of the field.
|
|
170
|
+
#
|
|
171
|
+
# @return [ nil ] Nil.
|
|
172
|
+
#
|
|
173
|
+
# @since 3.0.0
|
|
174
|
+
def unset(field)
|
|
175
|
+
query.update_all("$unset" => { field => true })
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Contextual
|
|
4
|
+
module Command
|
|
5
|
+
|
|
6
|
+
# The database command that is being built to send to the db.
|
|
7
|
+
#
|
|
8
|
+
# @example Get the command.
|
|
9
|
+
# command.command
|
|
10
|
+
#
|
|
11
|
+
# @return [ Hash ] The db command.
|
|
12
|
+
#
|
|
13
|
+
# @since 3.0.0
|
|
14
|
+
def command
|
|
15
|
+
@command ||= {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Get the criteria for the command.
|
|
19
|
+
#
|
|
20
|
+
# @example Get the criteria.
|
|
21
|
+
# command.criteria
|
|
22
|
+
#
|
|
23
|
+
# @return [ Criteria ] The criteria.
|
|
24
|
+
#
|
|
25
|
+
# @since 3.0.0
|
|
26
|
+
def criteria
|
|
27
|
+
@criteria
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Get the database session.
|
|
31
|
+
#
|
|
32
|
+
# @example Get the session.
|
|
33
|
+
# command.session
|
|
34
|
+
#
|
|
35
|
+
# @return [ Session ] The Moped session.
|
|
36
|
+
#
|
|
37
|
+
# @since 3.0.0
|
|
38
|
+
def session
|
|
39
|
+
criteria.klass.mongo_session
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Contextual
|
|
4
|
+
class FindAndModify
|
|
5
|
+
include Command
|
|
6
|
+
|
|
7
|
+
# Initialize the find and modify command, used for MongoDB's
|
|
8
|
+
# $findAndModify.
|
|
9
|
+
#
|
|
10
|
+
# @example Initialize the command.
|
|
11
|
+
# FindAndModify.new(criteria, { "$set" => { likes: 1 }})
|
|
12
|
+
#
|
|
13
|
+
# @param [ Criteria ] criteria The criteria.
|
|
14
|
+
# @param [ Hash ] update The updates.
|
|
15
|
+
# @param [ Hash ] options The command options.
|
|
16
|
+
#
|
|
17
|
+
# @option options [ true, false ] :new Return the updated document.
|
|
18
|
+
# @option options [ true, false ] :remove Delete the first document.
|
|
19
|
+
#
|
|
20
|
+
# @since 3.0.0
|
|
21
|
+
def initialize(criteria, update, options = {})
|
|
22
|
+
@criteria = criteria
|
|
23
|
+
command[:findandmodify] = criteria.klass.collection_name.to_s
|
|
24
|
+
command[:update] = update unless options[:remove]
|
|
25
|
+
command.merge!(options)
|
|
26
|
+
apply_criteria_options
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Get the result of the $findAndModify.
|
|
30
|
+
#
|
|
31
|
+
# @example Get the result.
|
|
32
|
+
# find_and_modify.result
|
|
33
|
+
#
|
|
34
|
+
# @return [ Hash ] The result of the command.
|
|
35
|
+
#
|
|
36
|
+
# @since 3.0.0
|
|
37
|
+
def result
|
|
38
|
+
session.with(consistency: :strong) do |session|
|
|
39
|
+
session.command(command)["value"]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
# Apply criteria specific options - query, sort, fields.
|
|
46
|
+
#
|
|
47
|
+
# @api private
|
|
48
|
+
#
|
|
49
|
+
# @example Apply the criteria options
|
|
50
|
+
# map_reduce.apply_criteria_options
|
|
51
|
+
#
|
|
52
|
+
# @return [ nil ] Nothing.
|
|
53
|
+
#
|
|
54
|
+
# @since 3.0.0
|
|
55
|
+
def apply_criteria_options
|
|
56
|
+
command[:query] = criteria.selector
|
|
57
|
+
if sort = criteria.options[:sort]
|
|
58
|
+
command[:sort] = sort
|
|
59
|
+
end
|
|
60
|
+
if fields = criteria.options[:fields]
|
|
61
|
+
command[:fields] = fields
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|