From 713bdd2aa1b7dc8f67b322768773b21ee77e94f1 Mon Sep 17 00:00:00 2001 From: Kenny Lindahl Date: Sun, 5 Mar 2023 10:40:39 +0100 Subject: [PATCH] feat: Add VariableWidthHistogramAggregation (#172) variable_width_histogram aggregation was added to Elasticsearch in v7.9.0. --- package.json | 9 +++- src/aggregations/bucket-aggregations/index.js | 1 + .../variable-width-histogram-aggregation.js | 45 +++++++++++++++++++ src/index.d.ts | 35 +++++++++++++++ src/index.js | 6 +++ ...riable-width-histogram-aggregation.test.js | 42 +++++++++++++++++ test/index.test.js | 3 ++ 7 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 src/aggregations/bucket-aggregations/variable-width-histogram-aggregation.js create mode 100644 test/aggregations-test/variable-width-histogram-aggregation.test.js diff --git a/package.json b/package.json index 40cdda4..0f34785 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,10 @@ "webpack-cli": "^3.0.8" }, "release": { - "branches": ["master", "next"] + "branches": [ + "master", + "next" + ] }, "lint-staged": { "src/**/*.js": [ @@ -99,6 +102,8 @@ "author": "Suhas Karanth ", "contributors": [ "austin ce ", - "ochan12 " + "ochan12 ", + "kennylindahl ", + "foxstarius " ] } diff --git a/src/aggregations/bucket-aggregations/index.js b/src/aggregations/bucket-aggregations/index.js index 9ab565b..bd85216 100644 --- a/src/aggregations/bucket-aggregations/index.js +++ b/src/aggregations/bucket-aggregations/index.js @@ -11,6 +11,7 @@ exports.ChildrenAggregation = require('./children-aggregation'); exports.CompositeAggregation = require('./composite-aggregation'); exports.DateHistogramAggregation = require('./date-histogram-aggregation'); exports.AutoDateHistogramAggregation = require('./auto-date-histogram-aggregation'); +exports.VariableWidthHistogramAggregation = require('./variable-width-histogram-aggregation'); exports.DateRangeAggregation = require('./date-range-aggregation'); exports.DiversifiedSamplerAggregation = require('./diversified-sampler-aggregation'); exports.FilterAggregation = require('./filter-aggregation'); diff --git a/src/aggregations/bucket-aggregations/variable-width-histogram-aggregation.js b/src/aggregations/bucket-aggregations/variable-width-histogram-aggregation.js new file mode 100644 index 0000000..1ed78ef --- /dev/null +++ b/src/aggregations/bucket-aggregations/variable-width-histogram-aggregation.js @@ -0,0 +1,45 @@ +'use strict'; + +const isNil = require('lodash.isnil'); + +const BucketAggregationBase = require('./bucket-aggregation-base'); + +/** + * This is a multi-bucket aggregation similar to Histogram. + * However, the width of each bucket is not specified. + * Rather, a target number of buckets is provided and bucket intervals are dynamically determined based on the document distribution. + * This is done using a simple one-pass document clustering algorithm that aims to obtain low distances between bucket centroids. + * Unlike other multi-bucket aggregations, the intervals will not necessarily have a uniform width. + * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-variablewidthhistogram-aggregation.html) + * + * NOTE: Only available in Elasticsearch v7.9.0+ + * @example + * const agg = esb.variableWidthHistogramAggregation('price', 'lowestPrice', 10) + * + * @param {string} name The name which will be used to refer to this aggregation. + * @param {string} [field] The field to aggregate on + * @param {number} [buckets] Bucket count to generate histogram over. + * + * @extends BucketAggregationBase + */ +class VariableWidthHistogramAggregation extends BucketAggregationBase { + // eslint-disable-next-line require-jsdoc + constructor(name, field, buckets) { + super(name, 'variable_width_histogram', field); + if (!isNil(buckets)) this._aggsDef.buckets = buckets; + } + + /** + * Sets the histogram bucket count. Buckets are generated based on this value. + * + * @param {number} buckets Bucket count to generate histogram over. + * @returns {VariableWidthHistogramAggregation} returns `this` so that calls can be chained + */ + buckets(buckets) { + this._aggsDef.buckets = buckets; + return this; + } +} + +module.exports = VariableWidthHistogramAggregation; diff --git a/src/index.d.ts b/src/index.d.ts index 1312832..6733953 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -5101,6 +5101,41 @@ declare namespace esb { buckets?: number ): AutoDateHistogramAggregation; + /** + * A multi-bucket aggregation similar to Histogram, but the width of each bucket is not specified. + * + * NOTE: Only available in Elasticsearch v7.9.0+ + * @param {string} name The name which will be used to refer to this aggregation. + * @param {string=} [field] The field to aggregate on + * @param {number=} [buckets] Bucket count to generate histogram over. + * @extends BucketAggregationBase + */ + export class VariableWidthHistogramAggregation extends BucketAggregationBase { + constructor(name: string, field?: string, buckets?: number); + + /** + * Sets the histogram bucket count. Buckets are generated based on this value. + * + * @param {number} buckets Bucket count to generate histogram over. + * @returns {VariableWidthHistogramAggregation} returns `this` so that calls can be chained + */ + buckets(buckets): this; + } + + /** + * A multi-bucket aggregation similar to Histogram, but the width of each bucket is not specified. + * + * @param {string} name The name which will be used to refer to this aggregation. + * @param {string=} [field] The field to aggregate on + * @param {number=} [buckets] Bucket count to generate histogram over. + * @extends BucketAggregationBase + */ + export function variableWidthHistogramAggregation( + name: string, + field?: string, + buckets?: number + ): VariableWidthHistogramAggregation; + /** * A multi-bucket aggregation similar to the histogram except it can only be applied on date values. * The interval can be specified by date/time expressions. diff --git a/src/index.js b/src/index.js index fdf8548..cb0dc4c 100644 --- a/src/index.js +++ b/src/index.js @@ -109,6 +109,7 @@ const { CompositeAggregation, DateHistogramAggregation, AutoDateHistogramAggregation, + VariableWidthHistogramAggregation, DateRangeAggregation, DiversifiedSamplerAggregation, FilterAggregation, @@ -394,6 +395,11 @@ exports.autoDateHistogramAggregation = constructorWrapper( AutoDateHistogramAggregation ); +exports.VariableWidthHistogramAggregation = VariableWidthHistogramAggregation; +exports.variableWidthHistogramAggregation = constructorWrapper( + VariableWidthHistogramAggregation +); + exports.DateRangeAggregation = DateRangeAggregation; exports.dateRangeAggregation = constructorWrapper(DateRangeAggregation); diff --git a/test/aggregations-test/variable-width-histogram-aggregation.test.js b/test/aggregations-test/variable-width-histogram-aggregation.test.js new file mode 100644 index 0000000..4e2e28b --- /dev/null +++ b/test/aggregations-test/variable-width-histogram-aggregation.test.js @@ -0,0 +1,42 @@ +import test from 'ava'; +import { VariableWidthHistogramAggregation } from '../../src'; +import { setsAggType } from '../_macros'; + +test( + setsAggType, + VariableWidthHistogramAggregation, + 'variable_width_histogram' +); + +test('constructor sets arguments', t => { + const value = new VariableWidthHistogramAggregation( + 'price', + 'lowestPrice', + 10 + ).toJSON(), + expected = { + price: { + variable_width_histogram: { field: 'lowestPrice', buckets: 10 } + } + }; + t.deepEqual(value, expected); +}); + +test('buckets is set', t => { + const value = new VariableWidthHistogramAggregation( + 'price', + 'lowestPrice', + 10 + ) + .buckets(20) + .toJSON(); + const expected = { + price: { + variable_width_histogram: { + field: 'lowestPrice', + buckets: 20 + } + } + }; + t.deepEqual(value, expected); +}); diff --git a/test/index.test.js b/test/index.test.js index 637963a..4c7ca5e 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -235,6 +235,9 @@ test('aggregations are exported', t => { t.truthy(esb.AutoDateHistogramAggregation); t.truthy(esb.autoDateHistogramAggregation); + t.truthy(esb.VariableWidthHistogramAggregation); + t.truthy(esb.variableWidthHistogramAggregation); + t.truthy(esb.DateRangeAggregation); t.truthy(esb.dateRangeAggregation);