Skip to content

Commit

Permalink
Added PercentilesAggregation
Browse files Browse the repository at this point in the history
  • Loading branch information
mattweber committed Mar 17, 2014
1 parent 08361b1 commit 0b0d82d
Show file tree
Hide file tree
Showing 4 changed files with 310 additions and 4 deletions.
116 changes: 116 additions & 0 deletions dist/elastic.js
Original file line number Diff line number Diff line change
Expand Up @@ -3664,6 +3664,122 @@
});
};

/**
@class
<p>A multi-value metrics aggregation that calculates one or more percentiles
over numeric values extracted from the aggregated documents. These values can
be extracted either from specific numeric fields in the documents, or be
generated by a provided script.</p>

@name ejs.PercentilesAggregation
@ejs aggregation
@borrows ejs.MetricsAggregationMixin.field as field
@borrows ejs.MetricsAggregationMixin.script as script
@borrows ejs.MetricsAggregationMixin.lang as lang
@borrows ejs.MetricsAggregationMixin.scriptValuesSorted as scriptValuesSorted
@borrows ejs.MetricsAggregationMixin.params as params
@borrows ejs.MetricsAggregationMixin.aggregation as aggregation
@borrows ejs.MetricsAggregationMixin.agg as agg
@borrows ejs.MetricsAggregationMixin._type as _type
@borrows ejs.MetricsAggregationMixin.toJSON as toJSON

@desc
<p>Aggregation that calculates one or more percentiles over numeric values
extracted from the aggregated documents.</p>

@param {String} name The name which be used to refer to this aggregation.

*/
ejs.PercentilesAggregation = function (name) {

var
_common = ejs.MetricsAggregationMixin(name, 'percentiles'),
agg = _common.toJSON();

return extend(_common, {

/**
Enable the response to be returned as a keyed object where the key is the
bucket interval.

@member ejs.PercentilesAggregation
@param {Boolean} trueFalse to enable keyed response or not
@returns {Object} returns <code>this</code> so that calls can be chained.
*/
keyed: function (trueFalse) {
if (trueFalse == null) {
return agg[name].percentiles.keyed;
}

agg[name].percentiles.keyed = trueFalse;
return this;
},

/**
Sets the percentile bucket array. Overwrites all existing values.

@member ejs.PercentilesAggregation
@param {Double[]} percents A double array of percentiles
@returns {Object} returns <code>this</code> so that calls can be chained.
*/
percents: function (percentArr) {
if (percentArr == null) {
return agg[name].percentiles.percents;
}

if (!isArray(percentArr)) {
throw new TypeError('Percents must be an array of doubles');
}

agg[name].percentiles.percents = percentArr;
return this;
},

/**
Add a single percentile to the current list of percentiles.

@member ejs.PercentilesAggregation
@param {Double} percentile A double percentile value to add
@returns {Object} returns <code>this</code> so that calls can be chained.
*/
percent: function (percentile) {
if (agg[name].percentiles.percents == null) {
agg[name].percentiles.percents = [];
}

if (percentile == null) {
return agg[name].percentiles.percents;
}

agg[name].percentiles.percents.push(percentile);
return this;
},

/**
Compression controls memory usage and approximation error. The compression
value limits the maximum number of nodes to 100 * compression. By
increasing the compression value, you can increase the accuracy of your
percentiles at the cost of more memory. Larger compression values also make
the algorithm slower since the underlying tree data structure grows in
size, resulting in more expensive operations. The default compression
value is 100.

@member ejs.PercentilesAggregation
@param {Integer} c The compression level.
@returns {Object} returns <code>this</code> so that calls can be chained.
*/
compression: function (c) {
if (c == null) {
return agg[name].percentiles.compression;
}

agg[name].percentiles.compression = c;
return this;
}

});
};

/**
@class
<p>A multi-bucket value source based aggregation that enables the user to
Expand Down
6 changes: 3 additions & 3 deletions dist/elastic.min.js

Large diffs are not rendered by default.

115 changes: 115 additions & 0 deletions src/aggregations/PercentilesAggregation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**
@class
<p>A multi-value metrics aggregation that calculates one or more percentiles
over numeric values extracted from the aggregated documents. These values can
be extracted either from specific numeric fields in the documents, or be
generated by a provided script.</p>
@name ejs.PercentilesAggregation
@ejs aggregation
@borrows ejs.MetricsAggregationMixin.field as field
@borrows ejs.MetricsAggregationMixin.script as script
@borrows ejs.MetricsAggregationMixin.lang as lang
@borrows ejs.MetricsAggregationMixin.scriptValuesSorted as scriptValuesSorted
@borrows ejs.MetricsAggregationMixin.params as params
@borrows ejs.MetricsAggregationMixin.aggregation as aggregation
@borrows ejs.MetricsAggregationMixin.agg as agg
@borrows ejs.MetricsAggregationMixin._type as _type
@borrows ejs.MetricsAggregationMixin.toJSON as toJSON
@desc
<p>Aggregation that calculates one or more percentiles over numeric values
extracted from the aggregated documents.</p>
@param {String} name The name which be used to refer to this aggregation.
*/
ejs.PercentilesAggregation = function (name) {

var
_common = ejs.MetricsAggregationMixin(name, 'percentiles'),
agg = _common.toJSON();

return extend(_common, {

/**
Enable the response to be returned as a keyed object where the key is the
bucket interval.
@member ejs.PercentilesAggregation
@param {Boolean} trueFalse to enable keyed response or not
@returns {Object} returns <code>this</code> so that calls can be chained.
*/
keyed: function (trueFalse) {
if (trueFalse == null) {
return agg[name].percentiles.keyed;
}

agg[name].percentiles.keyed = trueFalse;
return this;
},

/**
Sets the percentile bucket array. Overwrites all existing values.
@member ejs.PercentilesAggregation
@param {Double[]} percents A double array of percentiles
@returns {Object} returns <code>this</code> so that calls can be chained.
*/
percents: function (percentArr) {
if (percentArr == null) {
return agg[name].percentiles.percents;
}

if (!isArray(percentArr)) {
throw new TypeError('Percents must be an array of doubles');
}

agg[name].percentiles.percents = percentArr;
return this;
},

/**
Add a single percentile to the current list of percentiles.
@member ejs.PercentilesAggregation
@param {Double} percentile A double percentile value to add
@returns {Object} returns <code>this</code> so that calls can be chained.
*/
percent: function (percentile) {
if (agg[name].percentiles.percents == null) {
agg[name].percentiles.percents = [];
}

if (percentile == null) {
return agg[name].percentiles.percents;
}

agg[name].percentiles.percents.push(percentile);
return this;
},

/**
Compression controls memory usage and approximation error. The compression
value limits the maximum number of nodes to 100 * compression. By
increasing the compression value, you can increase the accuracy of your
percentiles at the cost of more memory. Larger compression values also make
the algorithm slower since the underlying tree data structure grows in
size, resulting in more expensive operations. The default compression
value is 100.
@member ejs.PercentilesAggregation
@param {Integer} c The compression level.
@returns {Object} returns <code>this</code> so that calls can be chained.
*/
compression: function (c) {
if (c == null) {
return agg[name].percentiles.compression;
}

agg[name].percentiles.compression = c;
return this;
}

});
};
77 changes: 76 additions & 1 deletion tests/aggregation_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ exports.aggregations = {
done();
},
exists: function (test) {
test.expect(13);
test.expect(14);

test.ok(ejs.GlobalAggregation, 'GlobalAggregation');
test.ok(ejs.FilterAggregation, 'FilterAggregation');
Expand All @@ -43,6 +43,81 @@ exports.aggregations = {
test.ok(ejs.CardinalityAggregation, 'CardinalityAggregation');
test.ok(ejs.MaxAggregation, 'MaxAggregation');
test.ok(ejs.MinAggregation, 'MinAggregation');
test.ok(ejs.PercentilesAggregation, 'PercentilesAggregation');

test.done();
},
PercentilesAggregation: function (test) {
test.expect(17);

var agg = ejs.PercentilesAggregation('myagg'),
ta1 = ejs.TermsAggregation('ta1').field('f1'),
expected,
doTest = function () {
test.deepEqual(agg.toJSON(), expected);
};

expected = {
myagg: {percentiles: {}}
};

test.ok(agg, 'PercentilesAggregation exists');
test.ok(agg.toJSON(), 'toJSON() works');
doTest();

agg.field('f1');
expected.myagg.percentiles.field = 'f1';
doTest();

agg.script('s1');
expected.myagg.percentiles.script = 's1';
doTest();

agg.lang('mvel');
expected.myagg.percentiles.lang = 'mvel';
doTest();

agg.scriptValuesSorted(false);
expected.myagg.percentiles.script_values_sorted = false;
doTest();

agg.params({p1: 'v1'});
expected.myagg.percentiles.params = {p1: 'v1'};
doTest();

agg.keyed(true);
expected.myagg.percentiles.keyed = true;
doTest();

agg.percents([95, 99]);
expected.myagg.percentiles.percents = [95, 99];
doTest();

agg.percent(99.9);
expected.myagg.percentiles.percents.push(99.9);
doTest();

agg.percents([98, 99, 99.9]);
expected.myagg.percentiles.percents = [98, 99, 99.9];
doTest();

agg.compression(200);
expected.myagg.percentiles.compression = 200;
doTest();

agg.agg(ta1);
expected.myagg.aggs = ta1.toJSON();
doTest();

test.strictEqual(agg._type(), 'aggregation');

test.throws(function () {
agg.agggregation('invalid');
}, TypeError);

test.throws(function () {
agg.percents('invalid');
}, TypeError);

test.done();
},
Expand Down

0 comments on commit 0b0d82d

Please sign in to comment.