Skip to content

Commit

Permalink
feat: Add ParentAggregation (#129)
Browse files Browse the repository at this point in the history
Parent aggregation was added in Elasticsearch v6.6
  • Loading branch information
rccoe authored Dec 23, 2020
1 parent 6da6fa3 commit d659f17
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ toc:
- IpRangeAggregation
- MissingAggregation
- NestedAggregation
- ParentAggregation
- RangeAggregation
- ReverseNestedAggregation
- SamplerAggregation
Expand Down
1 change: 1 addition & 0 deletions src/aggregations/bucket-aggregations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ exports.HistogramAggregation = require('./histogram-aggregation');
exports.IpRangeAggregation = require('./ip-range-aggregation');
exports.MissingAggregation = require('./missing-aggregation');
exports.NestedAggregation = require('./nested-aggregation');
exports.ParentAggregation = require('./parent-aggregation');
exports.RangeAggregation = require('./range-aggregation');
exports.ReverseNestedAggregation = require('./reverse-nested-aggregation');
exports.SamplerAggregation = require('./sampler-aggregation');
Expand Down
79 changes: 79 additions & 0 deletions src/aggregations/bucket-aggregations/parent-aggregation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
'use strict';

const isNil = require('lodash.isnil');

const BucketAggregationBase = require('./bucket-aggregation-base');

const ES_REF_URL =
'https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-parent-aggregation.html';

/**
* A special single bucket aggregation that enables aggregating
* from buckets on child document types to buckets on parent documents.
*
* This aggregation relies on the `_parent` field in the mapping.
*
* [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-parent-aggregation.html)
*
* @example
* const reqBody = esb.requestBodySearch()
* .agg(
* esb.termsAggregation('top-names', 'owner.display_name.keyword')
* .size(10)
* .agg(
* esb.parentAggregation('to-questions')
* .type('answer')
* .agg(
* esb.termsAggregation(
* 'top-tags',
* 'tags.keyword'
* ).size(10)
* )
* )
* )
* .size(0);
*
* @param {string} name The name which will be used to refer to this aggregation.
* @param {string=} type The type of the child document.
*
* @extends BucketAggregationBase
*/
class ParentAggregation extends BucketAggregationBase {
// eslint-disable-next-line require-jsdoc
constructor(name, type) {
super(name, 'parent');

if (!isNil(type)) this.type(type);
}

/**
* @override
* @throws {Error} This method cannot be called on ParentAggregation
*/
field() {
console.log(`Please refer ${ES_REF_URL}`);
throw new Error('field is not supported in ParentAggregation');
}

/**
* @override
* @throws {Error} This method cannot be called on ParentAggregation
*/
script() {
console.log(`Please refer ${ES_REF_URL}`);
throw new Error('script is not supported in ParentAggregation');
}

/**
* Sets the child type/mapping for aggregation.
*
* @param {string} type The child type that the buckets in the parent space should be mapped to.
* @returns {ParentAggregation} returns `this` so that calls can be chained
*/
type(type) {
this._aggsDef.type = type;
return this;
}
}

module.exports = ParentAggregation;
41 changes: 41 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5812,6 +5812,47 @@ declare namespace esb {
path?: string
): NestedAggregation;

/**
* A special single bucket aggregation that enables aggregating
* from buckets on child document types to buckets on parent documents.
* This aggregation relies on the `_parent` field in the mapping.
*
* NOTE: This query was added in elasticsearch v6.6.
*
* @param {string} name The name which will be used to refer to this aggregation.
* @extends BucketAggregationBase
*/
export class ParentAggregation extends BucketAggregationBase {
constructor(name: string);
/**
* @override
* @throws {Error} This method cannot be called on ParentAggregation
*/
field(): never;

/**
* @override
* @throws {Error} This method cannot be called on ParentAggregation
*/
script(): never;

/**
* Sets the child type/mapping for aggregation.
*
* @param {string} type The child type that the buckets in the parent space should be mapped to.
*/
type(type: string): this;
}

/**
* A special single bucket aggregation that enables aggregating
* from buckets on child document types to buckets on parent documents.
* This aggregation relies on the `_parent` field in the mapping.
*
* @param {string} name The name which will be used to refer to this aggregation.
*/
export function parentAggregation(name: string): ParentAggregation;

/**
* A multi-bucket value source based aggregation that enables the user to
* define a set of ranges - each representing a bucket. During the aggregation
Expand Down
4 changes: 4 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const {
IpRangeAggregation,
MissingAggregation,
NestedAggregation,
ParentAggregation,
RangeAggregation,
ReverseNestedAggregation,
SamplerAggregation,
Expand Down Expand Up @@ -421,6 +422,9 @@ exports.missingAggregation = constructorWrapper(MissingAggregation);
exports.NestedAggregation = NestedAggregation;
exports.nestedAggregation = constructorWrapper(NestedAggregation);

exports.ParentAggregation = ParentAggregation;
exports.parentAggregation = constructorWrapper(ParentAggregation);

exports.RangeAggregation = RangeAggregation;
exports.rangeAggregation = constructorWrapper(RangeAggregation);

Expand Down
31 changes: 31 additions & 0 deletions test/aggregations-test/parent-agg.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import test from 'ava';
import { ParentAggregation } from '../../src';
import { illegalCall, setsAggType } from '../_macros';

test(setsAggType, ParentAggregation, 'parent');
test(illegalCall, ParentAggregation, 'field', 'my_agg');
test(illegalCall, ParentAggregation, 'script', 'my_agg');

test('constructor sets type', t => {
const value = new ParentAggregation('to_questions', 'answer').toJSON();
const expected = {
to_questions: {
parent: {
type: 'answer'
}
}
};
t.deepEqual(value, expected);
});

test('type is set', t => {
const value = new ParentAggregation('to_questions').type('answer').toJSON();
const expected = {
to_questions: {
parent: {
type: 'answer'
}
}
};
t.deepEqual(value, expected);
});
3 changes: 3 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ test('aggregations are exported', t => {
t.truthy(esb.NestedAggregation);
t.truthy(esb.nestedAggregation);

t.truthy(esb.ParentAggregation);
t.truthy(esb.parentAggregation);

t.truthy(esb.RangeAggregation);
t.truthy(esb.rangeAggregation);

Expand Down

0 comments on commit d659f17

Please sign in to comment.