Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Bug when aggregating on field that doesn't always exist #2334

Merged
merged 2 commits into from

3 participants

@jpmckinney

When a field only sometimes exists, the aggregates behave oddly. In both the specs, 50 should be the min. But in one case it's nil and in another it's 100 (!).

@jpmckinney

Testing that the field is not null in the reduce function gets the specs to pass.

@travisbot

This pull request fails (merged 30dbb21 into 68f4555).

@travisbot

This pull request fails (merged 418ae6e into 68f4555).

@jpmckinney

Hmm, the JRuby failures seem unrelated.

@durran
Owner

Sweet - thanks! (Yes the failures are unrelated, pulling in)

@durran durran merged commit 7fe4b58 into mongoid:master
@durran durran added the fixed label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
8 lib/mongoid/contextual/aggregable/mongo.rb
@@ -167,10 +167,12 @@ def reducer
function(key, values) {
var agg = { count: 0, max: null, min: null, sum: 0 };
values.forEach(function(val) {
- if (agg.max == null || val.max > agg.max) agg.max = val.max;
- if (agg.min == null || val.max < agg.min) agg.min = val.max;
+ if (val.max !== null) {
+ if (agg.max == null || val.max > agg.max) agg.max = val.max;
+ if (agg.min == null || val.max < agg.min) agg.min = val.max;
+ agg.sum += val.sum;
+ }
agg.count += 1;
- agg.sum += val.sum;
});
return agg;
}}
View
50 spec/mongoid/contextual/aggregable/mongo_spec.rb
@@ -110,6 +110,56 @@
end
end
+ context "when the field sometimes exists" do
+ let!(:oasis) do
+ Band.create(name: "Oasis", likes: 50)
+ end
+
+ let!(:radiohead) do
+ Band.create(name: "Radiohead")
+ end
+
+ context "and the field doesn't exist on the last document" do
+ let(:criteria) do
+ Band.all
+ end
+
+ let(:context) do
+ Mongoid::Contextual::Mongo.new(criteria)
+ end
+
+ let(:aggregates) do
+ context.aggregates(:likes)
+ end
+
+ it "returns a min" do
+ aggregates["min"].should eq(50)
+ end
+ end
+
+ context "and the field doesn't exist on the before-last document" do
+ let!(:u2) do
+ Band.create(name: "U2", likes: 100)
+ end
+
+ let(:criteria) do
+ Band.all
+ end
+
+ let(:context) do
+ Mongoid::Contextual::Mongo.new(criteria)
+ end
+
+ let(:aggregates) do
+ context.aggregates(:likes)
+ end
+
+ it "returns a min" do
+ aggregates["min"].should eq(50)
+ end
+ end
+ end
+
context "when there are no matching documents" do
let(:criteria) do
Something went wrong with that request. Please try again.