mongoid 0.11.7 → 0.11.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.
- data/HISTORY +4 -0
- data/VERSION +1 -1
- data/lib/mongoid/criteria.rb +48 -10
- data/lib/mongoid/extensions/time/conversions.rb +2 -1
- data/lib/mongoid/finders.rb +30 -0
- data/mongoid.gemspec +1 -1
- data/spec/integration/mongoid/criteria_spec.rb +36 -0
- data/spec/unit/mongoid/criteria_spec.rb +55 -3
- data/spec/unit/mongoid/extensions/time/conversions_spec.rb +8 -0
- data/spec/unit/mongoid/finders_spec.rb +28 -0
- metadata +1 -1
data/HISTORY
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.11.
|
1
|
+
0.11.8
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -422,23 +422,48 @@ module Mongoid #:nodoc:
|
|
422
422
|
end
|
423
423
|
|
424
424
|
SUM_REDUCE = "function(obj, prev) { prev.sum += obj.[field]; }"
|
425
|
-
# Sum the criteria.
|
425
|
+
# Sum the criteria.
|
426
|
+
#
|
427
|
+
# This will take the internally built selector and options
|
426
428
|
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
427
429
|
# collection itself will be retrieved from the class provided, and once the
|
428
430
|
# query has returned it will provided a grouping of keys with sums.
|
429
431
|
#
|
430
432
|
# Example:
|
431
433
|
#
|
432
|
-
# <tt>criteria.
|
434
|
+
# <tt>criteria.sum(:age)</tt>
|
433
435
|
def sum(field)
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
436
|
+
grouped(:sum, field.to_s, SUM_REDUCE)
|
437
|
+
end
|
438
|
+
|
439
|
+
MIN_REDUCE = "function(obj, prev) { if (prev.max > obj.[field]) { prev.max = obj.[field]; } }"
|
440
|
+
# Return the min value for a field.
|
441
|
+
#
|
442
|
+
# This will take the internally built selector and options
|
443
|
+
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
444
|
+
# collection itself will be retrieved from the class provided, and once the
|
445
|
+
# query has returned it will provided a grouping of keys with sums.
|
446
|
+
#
|
447
|
+
# Example:
|
448
|
+
#
|
449
|
+
# <tt>criteria.min(:age)</tt>
|
450
|
+
def min(field)
|
451
|
+
grouped(:min, field.to_s, MIN_REDUCE)
|
452
|
+
end
|
453
|
+
|
454
|
+
MAX_REDUCE = "function(obj, prev) { if (prev.max < obj.[field]) { prev.max = obj.[field]; } }"
|
455
|
+
# Return the max value for a field.
|
456
|
+
#
|
457
|
+
# This will take the internally built selector and options
|
458
|
+
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
459
|
+
# collection itself will be retrieved from the class provided, and once the
|
460
|
+
# query has returned it will provided a grouping of keys with sums.
|
461
|
+
#
|
462
|
+
# Example:
|
463
|
+
#
|
464
|
+
# <tt>criteria.max(:age)</tt>
|
465
|
+
def max(field)
|
466
|
+
grouped(:max, field.to_s, MAX_REDUCE)
|
442
467
|
end
|
443
468
|
|
444
469
|
# Translate the supplied arguments into a +Criteria+ object.
|
@@ -536,5 +561,18 @@ module Mongoid #:nodoc:
|
|
536
561
|
def update_selector(attributes, operator)
|
537
562
|
attributes.each { |key, value| @selector[key] = { operator => value } }; self
|
538
563
|
end
|
564
|
+
|
565
|
+
# Common functionality for grouping operations. Currently used by min, max
|
566
|
+
# and sum. Will gsub the field name in the supplied reduce function.
|
567
|
+
def grouped(start, field, reduce)
|
568
|
+
collection = @klass.collection.group(
|
569
|
+
nil,
|
570
|
+
@selector,
|
571
|
+
{ start => 0 },
|
572
|
+
reduce.gsub("[field]", field),
|
573
|
+
true
|
574
|
+
)
|
575
|
+
collection.first[start.to_s]
|
576
|
+
end
|
539
577
|
end
|
540
578
|
end
|
data/lib/mongoid/finders.rb
CHANGED
@@ -76,6 +76,21 @@ module Mongoid #:nodoc:
|
|
76
76
|
find(:last, *args)
|
77
77
|
end
|
78
78
|
|
79
|
+
# Convenience method for returning the max value of a field.
|
80
|
+
#
|
81
|
+
# Options:
|
82
|
+
#
|
83
|
+
# field: The field to use when calculating the max.
|
84
|
+
#
|
85
|
+
# Example:
|
86
|
+
#
|
87
|
+
# <tt>Person.max(:age)</tt>
|
88
|
+
#
|
89
|
+
# Returns: <tt>Float</tt> max value.
|
90
|
+
def max(field)
|
91
|
+
Criteria.new(self).max(field)
|
92
|
+
end
|
93
|
+
|
79
94
|
# Will execute a +Criteria+ based on the +DynamicFinder+ that gets
|
80
95
|
# generated.
|
81
96
|
#
|
@@ -94,6 +109,21 @@ module Mongoid #:nodoc:
|
|
94
109
|
results ? results : dyna.create(self)
|
95
110
|
end
|
96
111
|
|
112
|
+
# Convenience method for returning the min value of a field.
|
113
|
+
#
|
114
|
+
# Options:
|
115
|
+
#
|
116
|
+
# field: The field to use when calculating the min.
|
117
|
+
#
|
118
|
+
# Example:
|
119
|
+
#
|
120
|
+
# <tt>Person.min(:age)</tt>
|
121
|
+
#
|
122
|
+
# Returns: <tt>Float</tt> min value.
|
123
|
+
def min(field)
|
124
|
+
Criteria.new(self).min(field)
|
125
|
+
end
|
126
|
+
|
97
127
|
# Find all documents in paginated fashion given the supplied arguments.
|
98
128
|
# If no parameters are passed just default to offset 0 and limit 20.
|
99
129
|
#
|
data/mongoid.gemspec
CHANGED
@@ -2,6 +2,42 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Mongoid::Criteria do
|
4
4
|
|
5
|
+
describe "#max" do
|
6
|
+
|
7
|
+
before do
|
8
|
+
10.times do |n|
|
9
|
+
Person.create(:title => "Sir", :age => (n * 10), :aliases => ["D", "Durran"])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
Person.delete_all
|
15
|
+
end
|
16
|
+
|
17
|
+
it "provides sums for all the fields provided" do
|
18
|
+
Person.criteria.max(:age).should == 90.0
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#min" do
|
24
|
+
|
25
|
+
before do
|
26
|
+
10.times do |n|
|
27
|
+
Person.create(:title => "Sir", :age => (n * 10), :aliases => ["D", "Durran"])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
after do
|
32
|
+
Person.delete_all
|
33
|
+
end
|
34
|
+
|
35
|
+
it "provides sums for all the fields provided" do
|
36
|
+
Person.criteria.min(:age).should == 0.0
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
5
41
|
describe "#sum" do
|
6
42
|
|
7
43
|
before do
|
@@ -492,6 +492,27 @@ describe Mongoid::Criteria do
|
|
492
492
|
|
493
493
|
end
|
494
494
|
|
495
|
+
describe "#max" do
|
496
|
+
|
497
|
+
before do
|
498
|
+
@reduce = "function(obj, prev) { if (prev.max < obj.age) { prev.max = obj.age; } }"
|
499
|
+
@collection = mock
|
500
|
+
Person.expects(:collection).returns(@collection)
|
501
|
+
end
|
502
|
+
|
503
|
+
it "calls group on the collection with the aggregate js" do
|
504
|
+
@collection.expects(:group).with(
|
505
|
+
nil,
|
506
|
+
{:_type => { "$in" => ["Doctor", "Person"] } },
|
507
|
+
{:max => 0},
|
508
|
+
@reduce,
|
509
|
+
true
|
510
|
+
).returns([{"max" => 200.0}])
|
511
|
+
@criteria.max(:age).should == 200.0
|
512
|
+
end
|
513
|
+
|
514
|
+
end
|
515
|
+
|
495
516
|
describe "#merge" do
|
496
517
|
|
497
518
|
before do
|
@@ -591,11 +612,36 @@ describe Mongoid::Criteria do
|
|
591
612
|
|
592
613
|
end
|
593
614
|
|
615
|
+
describe "#min" do
|
616
|
+
|
617
|
+
before do
|
618
|
+
@reduce = "function(obj, prev) { if (prev.max > obj.age) { prev.max = obj.age; } }"
|
619
|
+
@collection = mock
|
620
|
+
Person.expects(:collection).returns(@collection)
|
621
|
+
end
|
622
|
+
|
623
|
+
it "calls group on the collection with the aggregate js" do
|
624
|
+
@collection.expects(:group).with(
|
625
|
+
nil,
|
626
|
+
{:_type => { "$in" => ["Doctor", "Person"] } },
|
627
|
+
{:min => 0},
|
628
|
+
@reduce,
|
629
|
+
true
|
630
|
+
).returns([{"min" => 4.0}])
|
631
|
+
@criteria.min(:age).should == 4.0
|
632
|
+
end
|
633
|
+
|
634
|
+
end
|
635
|
+
|
594
636
|
describe "#not_in" do
|
595
637
|
|
596
638
|
it "adds the exclusion to the selector" do
|
597
639
|
@criteria.not_in(:title => ["title1", "title2"], :text => ["test"])
|
598
|
-
@criteria.selector.should == {
|
640
|
+
@criteria.selector.should == {
|
641
|
+
:_type => { "$in" => ["Doctor", "Person"] },
|
642
|
+
:title => { "$nin" => ["title1", "title2"] },
|
643
|
+
:text => { "$nin" => ["test"] }
|
644
|
+
}
|
599
645
|
end
|
600
646
|
|
601
647
|
it "returns self" do
|
@@ -851,8 +897,14 @@ describe Mongoid::Criteria do
|
|
851
897
|
end
|
852
898
|
|
853
899
|
it "calls group on the collection with the aggregate js" do
|
854
|
-
@collection.expects(:group).with(
|
855
|
-
|
900
|
+
@collection.expects(:group).with(
|
901
|
+
nil,
|
902
|
+
{:_type => { "$in" => ["Doctor", "Person"] } },
|
903
|
+
{:sum => 0},
|
904
|
+
@reduce,
|
905
|
+
true
|
906
|
+
).returns([{"sum" => 50.0}])
|
907
|
+
@criteria.sum(:age).should == 50.0
|
856
908
|
end
|
857
909
|
|
858
910
|
end
|
@@ -29,6 +29,14 @@ describe Mongoid::Extensions::Time::Conversions do
|
|
29
29
|
|
30
30
|
end
|
31
31
|
|
32
|
+
context "when value is already a utc time" do
|
33
|
+
|
34
|
+
it "returns the time" do
|
35
|
+
Time.set(@time.utc).should == @time.utc
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
32
40
|
context "when value is nil" do
|
33
41
|
|
34
42
|
it "returns nil" do
|
@@ -197,6 +197,20 @@ describe Mongoid::Finders do
|
|
197
197
|
|
198
198
|
end
|
199
199
|
|
200
|
+
describe ".max" do
|
201
|
+
|
202
|
+
before do
|
203
|
+
@criteria = mock
|
204
|
+
end
|
205
|
+
|
206
|
+
it "returns the sum of a new criteria" do
|
207
|
+
Mongoid::Criteria.expects(:new).returns(@criteria)
|
208
|
+
@criteria.expects(:max).with(:age).returns(50.0)
|
209
|
+
Person.max(:age).should == 50.0
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
200
214
|
describe ".method_missing" do
|
201
215
|
|
202
216
|
context "with a finder method name" do
|
@@ -250,6 +264,20 @@ describe Mongoid::Finders do
|
|
250
264
|
|
251
265
|
end
|
252
266
|
|
267
|
+
describe ".min" do
|
268
|
+
|
269
|
+
before do
|
270
|
+
@criteria = mock
|
271
|
+
end
|
272
|
+
|
273
|
+
it "returns the sum of a new criteria" do
|
274
|
+
Mongoid::Criteria.expects(:new).returns(@criteria)
|
275
|
+
@criteria.expects(:min).with(:age).returns(50.0)
|
276
|
+
Person.min(:age).should == 50.0
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
|
253
281
|
describe ".paginate" do
|
254
282
|
|
255
283
|
before do
|