Skip to content

Commit

Permalink
[data.search.aggs]: Expression functions for bucket agg types (elasti…
Browse files Browse the repository at this point in the history
…c#64772)

* [data.search.aggs]: Expression functions for bucket agg types - ranges agg types + significant terms

* new portion of changes

* add geo_tile_fn

* add geo_hash_fn

* Update src/plugins/data/public/search/aggs/buckets/filter_fn.ts

Co-authored-by: Luke Elmers <[email protected]>

* Update src/plugins/data/public/search/aggs/buckets/geo_tile_fn.ts

Co-authored-by: Luke Elmers <[email protected]>

* Update src/plugins/data/public/search/aggs/buckets/geo_hash_fn.ts

Co-authored-by: Luke Elmers <[email protected]>

* Update src/plugins/data/public/search/aggs/buckets/ip_range_fn.ts

Co-authored-by: Luke Elmers <[email protected]>

* Update src/plugins/data/public/search/aggs/buckets/geo_hash_fn.ts

Co-authored-by: Luke Elmers <[email protected]>

* Update src/plugins/data/public/search/aggs/buckets/geo_hash_fn.ts

Co-authored-by: Luke Elmers <[email protected]>

* Update src/plugins/data/public/search/aggs/buckets/geo_hash_fn.ts

Co-authored-by: Luke Elmers <[email protected]>

* create BaseAggParams

* add filters_fn

* add histogram / date_histogram expression functions

* cleanup

* terms - order should be optional

* add custom label params

Co-authored-by: Luke Elmers <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
3 people committed May 5, 2020
1 parent ea04828 commit dfac2b8
Show file tree
Hide file tree
Showing 43 changed files with 2,551 additions and 78 deletions.
1 change: 1 addition & 0 deletions src/plugins/data/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Component } from 'react';
import { CoreSetup } from 'src/core/public';
import { CoreStart } from 'kibana/public';
import { CoreStart as CoreStart_2 } from 'src/core/public';
import { Ensure } from '@kbn/utility-types';
import { EuiButtonEmptyProps } from '@elastic/eui';
import { EuiComboBoxProps } from '@elastic/eui';
import { EuiConfirmModalProps } from '@elastic/eui';
Expand Down
23 changes: 14 additions & 9 deletions src/plugins/data/public/search/aggs/agg_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import _ from 'lodash';
import { i18n } from '@kbn/i18n';
import { Assign } from '@kbn/utility-types';
import { Assign, Ensure } from '@kbn/utility-types';
import { ExpressionAstFunction, ExpressionAstArgument } from 'src/plugins/expressions/public';
import { IAggType } from './agg_type';
import { writeParams } from './agg_params';
Expand All @@ -31,17 +31,22 @@ import { FieldFormatsStart } from '../../field_formats';

type State = string | number | boolean | null | undefined | SerializableState;

interface SerializableState {
/** @internal **/
export interface SerializableState {
[key: string]: State | State[];
}

export interface AggConfigSerialized {
type: string;
enabled?: boolean;
id?: string;
params?: SerializableState;
schema?: string;
}
/** @internal **/
export type AggConfigSerialized = Ensure<
{
type: string;
enabled?: boolean;
id?: string;
params?: SerializableState;
schema?: string;
},
SerializableState
>;

export interface AggConfigDependencies {
fieldFormats: FieldFormatsStart;
Expand Down
25 changes: 24 additions & 1 deletion src/plugins/data/public/search/aggs/agg_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,29 @@ export const getAggTypes = ({
],
});

/** Buckets: **/
import { aggFilter } from './buckets/filter_fn';
import { aggFilters } from './buckets/filters_fn';
import { aggSignificantTerms } from './buckets/significant_terms_fn';
import { aggIpRange } from './buckets/ip_range_fn';
import { aggDateRange } from './buckets/date_range_fn';
import { aggRange } from './buckets/range_fn';
import { aggGeoTile } from './buckets/geo_tile_fn';
import { aggGeoHash } from './buckets/geo_hash_fn';
import { aggHistogram } from './buckets/histogram_fn';
import { aggDateHistogram } from './buckets/date_histogram_fn';
import { aggTerms } from './buckets/terms_fn';

export const getAggTypesFunctions = () => [aggTerms];
export const getAggTypesFunctions = () => [
aggFilter,
aggFilters,
aggSignificantTerms,
aggIpRange,
aggDateRange,
aggRange,
aggGeoTile,
aggGeoHash,
aggDateHistogram,
aggHistogram,
aggTerms,
];
18 changes: 17 additions & 1 deletion src/plugins/data/public/search/aggs/buckets/date_histogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ import { BucketAggType, IBucketAggConfig } from './bucket_agg_type';
import { BUCKET_TYPES } from './bucket_agg_types';
import { createFilterDateHistogram } from './create_filter/date_histogram';
import { intervalOptions } from './_interval_options';
import { dateHistogramInterval } from '../../../../common';
import { dateHistogramInterval, TimeRange } from '../../../../common';
import { writeParams } from '../agg_params';
import { isMetricAggType } from '../metrics/metric_agg_type';

import { FIELD_FORMAT_IDS, KBN_FIELD_TYPES } from '../../../../common';
import { TimefilterContract } from '../../../query';
import { QuerySetup } from '../../../query/query_service';
import { GetInternalStartServicesFn } from '../../../types';
import { BaseAggParams } from '../types';
import { ExtendedBounds } from './lib/extended_bounds';

const detectedTimezone = moment.tz.guess();
const tzOffset = moment().format('Z');
Expand Down Expand Up @@ -67,6 +69,19 @@ export function isDateHistogramBucketAggConfig(agg: any): agg is IBucketDateHist
return Boolean(agg.buckets);
}

export interface AggParamsDateHistogram extends BaseAggParams {
field?: string;
timeRange?: TimeRange;
useNormalizedEsInterval?: boolean;
scaleMetricValues?: boolean;
interval?: string;
time_zone?: string;
drop_partials?: boolean;
format?: string;
min_doc_count?: number;
extended_bounds?: ExtendedBounds;
}

export const getDateHistogramBucketAgg = ({
uiSettings,
query,
Expand All @@ -89,6 +104,7 @@ export const getDateHistogramBucketAgg = ({
}

const field = agg.getFieldDisplayName();

return i18n.translate('data.search.aggs.buckets.dateHistogramLabel', {
defaultMessage: '{fieldName} per {intervalDescription}',
values: {
Expand Down
120 changes: 120 additions & 0 deletions src/plugins/data/public/search/aggs/buckets/date_histogram_fn.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { functionWrapper } from '../test_helpers';
import { aggDateHistogram } from './date_histogram_fn';

describe('agg_expression_functions', () => {
describe('aggDateHistogram', () => {
const fn = functionWrapper(aggDateHistogram());

test('fills in defaults when only required args are provided', () => {
const actual = fn({});
expect(actual).toMatchInlineSnapshot(`
Object {
"type": "agg_type",
"value": Object {
"enabled": true,
"id": undefined,
"params": Object {
"customLabel": undefined,
"drop_partials": undefined,
"extended_bounds": undefined,
"field": undefined,
"format": undefined,
"interval": undefined,
"json": undefined,
"min_doc_count": undefined,
"scaleMetricValues": undefined,
"timeRange": undefined,
"time_zone": undefined,
"useNormalizedEsInterval": undefined,
},
"schema": undefined,
"type": "date_histogram",
},
}
`);
});

test('includes optional params when they are provided', () => {
const actual = fn({
field: 'field',
timeRange: JSON.stringify({
from: 'from',
to: 'to',
}),
useNormalizedEsInterval: true,
scaleMetricValues: true,
interval: 'interval',
time_zone: 'time_zone',
drop_partials: false,
format: 'format',
min_doc_count: 1,
extended_bounds: JSON.stringify({
min: 1,
max: 2,
}),
});

expect(actual.value).toMatchInlineSnapshot(`
Object {
"enabled": true,
"id": undefined,
"params": Object {
"customLabel": undefined,
"drop_partials": false,
"extended_bounds": Object {
"max": 2,
"min": 1,
},
"field": "field",
"format": "format",
"interval": "interval",
"json": undefined,
"min_doc_count": 1,
"scaleMetricValues": true,
"timeRange": Object {
"from": "from",
"to": "to",
},
"time_zone": "time_zone",
"useNormalizedEsInterval": true,
},
"schema": undefined,
"type": "date_histogram",
}
`);
});

test('correctly parses json string argument', () => {
const actual = fn({
json: '{ "foo": true }',
});

expect(actual.value.params.json).toEqual({ foo: true });

expect(() => {
fn({
json: '/// intentionally malformed json ///',
});
}).toThrowErrorMatchingInlineSnapshot(`"Unable to parse json argument string"`);
});
});
});
Loading

0 comments on commit dfac2b8

Please sign in to comment.