Skip to content

Commit

Permalink
Clean up date histogram agg type. (#58805) (#59390)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeelmers authored Mar 5, 2020
1 parent 703cebc commit 3905bea
Show file tree
Hide file tree
Showing 39 changed files with 760 additions and 656 deletions.
2 changes: 1 addition & 1 deletion src/legacy/core_plugins/data/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ export {
convertIPRangeToString,
intervalOptions, // only used in Discover
isDateHistogramBucketAggConfig,
setBounds,
isStringType,
isType,
isValidInterval,
Expand All @@ -80,6 +79,7 @@ export {
Schemas,
siblingPipelineType,
termsAggFilter,
toAbsoluteDates,
// search_source
getRequestInspectorStats,
getResponseInspectorStats,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { identity } from 'lodash';

import { AggConfig, IAggConfig } from './agg_config';
import { AggConfigs, CreateAggConfigParams } from './agg_configs';
import { AggType } from './agg_types';
import { AggType } from './agg_type';
import { AggTypesRegistryStart } from './agg_types_registry';
import { mockDataServices, mockAggTypesRegistry } from './test_helpers';
import { IndexPatternField, IndexPattern } from '../../../../../../plugins/data/public';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,6 @@ export class AggConfig {
fieldIsTimeField() {
const indexPattern = this.getIndexPattern();
if (!indexPattern) return false;
// @ts-ignore
const timeFieldName = indexPattern.timeFieldName;
return timeFieldName && this.fieldName() === timeFieldName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ describe('AggConfigs', () => {
let typesRegistry: AggTypesRegistryStart;

beforeEach(() => {
mockDataServices();
indexPattern = stubIndexPatternWithFields as IndexPattern;
typesRegistry = mockAggTypesRegistry();
});
Expand Down Expand Up @@ -296,7 +297,6 @@ describe('AggConfigs', () => {
]);

beforeEach(() => {
mockDataServices();
indexPattern = stubIndexPattern as IndexPattern;
indexPattern.fields.getByName = name => (name as unknown) as IndexPatternField;
});
Expand Down
24 changes: 0 additions & 24 deletions src/legacy/core_plugins/data/public/search/aggs/agg_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,3 @@ export const aggTypes = {
geoTileBucketAgg,
],
};

export { AggType } from './agg_type';
export { AggConfig } from './agg_config';
export { AggConfigs } from './agg_configs';
export { FieldParamType } from './param_types';
export { aggTypeFieldFilters } from './param_types/filter';
export { parentPipelineAggHelper } from './metrics/lib/parent_pipeline_agg_helper';

// static code
export { AggParamType } from './param_types/agg';
export { AggGroupNames, aggGroupNamesMap } from './agg_groups';
export { intervalOptions } from './buckets/_interval_options'; // only used in Discover
export { isDateHistogramBucketAggConfig, setBounds } from './buckets/date_histogram';
export { termsAggFilter } from './buckets/terms';
export { isType, isStringType } from './buckets/migrate_include_exclude_format';
export { CidrMask } from './buckets/lib/cidr_mask';
export { convertDateRangeToString } from './buckets/date_range';
export { convertIPRangeToString } from './buckets/ip_range';
export { aggTypeFilters, propFilter } from './filter';
export { OptionedParamType } from './param_types/optioned';
export { isValidJson, isValidInterval } from './utils';
export { BUCKET_TYPES } from './buckets/bucket_agg_types';
export { METRIC_TYPES } from './metrics/metric_agg_types';
export { ISchemas, Schema, Schemas } from './schemas';
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ import { dateHistogramBucketAgg, IBucketDateHistogramAggConfig } from '../date_h
import { BUCKET_TYPES } from '../bucket_agg_types';
import { RangeFilter } from '../../../../../../../../plugins/data/public';

// TODO: remove this once time buckets is migrated
jest.mock('ui/new_platform');

describe('AggConfig Filters', () => {
describe('date_histogram', () => {
beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ import _ from 'lodash';
import moment from 'moment-timezone';
import { i18n } from '@kbn/i18n';

// TODO need to move TimeBuckets
import { TimeBuckets } from 'ui/time_buckets';
import { TimeBuckets } from './lib/time_buckets';
import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
import { BUCKET_TYPES } from './bucket_agg_types';
import { createFilterDateHistogram } from './create_filter/date_histogram';
Expand All @@ -31,34 +30,42 @@ import { dateHistogramInterval } from '../../../../common';
import { writeParams } from '../agg_params';
import { isMetricAggType } from '../metrics/metric_agg_type';

import { KBN_FIELD_TYPES } from '../../../../../../../plugins/data/public';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { getQueryService, getUiSettings } from '../../../../../../../plugins/data/public/services';
import {
fieldFormats,
KBN_FIELD_TYPES,
TimefilterContract,
} from '../../../../../../../plugins/data/public';
import {
getFieldFormats,
getQueryService,
getUiSettings,
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
} from '../../../../../../../plugins/data/public/services';

const detectedTimezone = moment.tz.guess();
const tzOffset = moment().format('Z');

const getInterval = (agg: IBucketAggConfig): string => _.get(agg, ['params', 'interval']);

export const setBounds = (agg: IBucketDateHistogramAggConfig, force?: boolean) => {
const { timefilter } = getQueryService().timefilter;
if (agg.buckets._alreadySet && !force) return;
agg.buckets._alreadySet = true;
const updateTimeBuckets = (
agg: IBucketDateHistogramAggConfig,
timefilter: TimefilterContract,
customBuckets?: IBucketDateHistogramAggConfig['buckets']
) => {
const bounds = agg.params.timeRange ? timefilter.calculateBounds(agg.params.timeRange) : null;
agg.buckets.setBounds(agg.fieldIsTimeField() && bounds);
const buckets = customBuckets || agg.buckets;
buckets.setBounds(agg.fieldIsTimeField() && bounds);
buckets.setInterval(agg.params.interval);
};

// will be replaced by src/legacy/ui/public/time_buckets/time_buckets.js
interface TimeBuckets {
_alreadySet?: boolean;
// TODO: Need to incorporate these properly into TimeBuckets
interface ITimeBuckets {
setBounds: Function;
getScaledDateFormatter: Function;
getScaledDateFormat: TimeBuckets['getScaledDateFormat'];
setInterval: Function;
getInterval: Function;
}

export interface IBucketDateHistogramAggConfig extends IBucketAggConfig {
buckets: TimeBuckets;
buckets: ITimeBuckets;
}

export function isDateHistogramBucketAggConfig(agg: any): agg is IBucketDateHistogramAggConfig {
Expand Down Expand Up @@ -91,24 +98,37 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
},
createFilter: createFilterDateHistogram,
decorateAggConfig() {
const uiSettings = getUiSettings();
let buckets: any;

return {
buckets: {
configurable: true,
get() {
if (buckets) return buckets;

buckets = new TimeBuckets();
buckets.setInterval(getInterval(this));
setBounds(this);
const { timefilter } = getQueryService().timefilter;
buckets = new TimeBuckets({ uiSettings });
updateTimeBuckets(this, timefilter, buckets);

return buckets;
},
} as any,
};
},
getFormat(agg) {
return agg.buckets.getScaledDateFormatter();
const DateFieldFormat = getFieldFormats().getType(fieldFormats.FIELD_FORMAT_IDS.DATE);

if (!DateFieldFormat) {
throw new Error('Unable to retrieve Date Field Format');
}

return new DateFieldFormat(
{
pattern: agg.buckets.getScaledDateFormat(),
},
(key: string) => getUiSettings().get(key)
);
},
params: [
{
Expand All @@ -122,8 +142,6 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
if (_.get(agg, 'params.interval') === 'auto' && !agg.fieldIsTimeField()) {
delete agg.params.interval;
}

setBounds(agg, true);
},
},
{
Expand Down Expand Up @@ -161,12 +179,10 @@ export const dateHistogramBucketAgg = new BucketAggType<IBucketDateHistogramAggC
},
default: 'auto',
options: intervalOptions,
modifyAggConfigOnSearchRequestStart(agg: IBucketDateHistogramAggConfig) {
setBounds(agg, true);
},
write(agg, output, aggs) {
setBounds(agg, true);
agg.buckets.setInterval(getInterval(agg));
const { timefilter } = getQueryService().timefilter;
updateTimeBuckets(agg, timefilter);

const { useNormalizedEsInterval, scaleMetricValues } = agg.params;
const interval = agg.buckets.getInterval(useNormalizedEsInterval);
output.bucketInterval = interval;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,12 @@ export interface DateRangeKey {
to: number;
}

export const convertDateRangeToString = (
{ from, to }: DateRangeKey,
format: (val: any) => string
) => {
export function convertDateRangeToString({ from, to }: DateRangeKey, format: (val: any) => string) {
if (!from) {
return 'Before ' + format(to);
} else if (!to) {
return 'After ' + format(from);
} else {
return format(from) + ' to ' + format(to);
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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 dateMath from '@elastic/datemath';
import { TimeBuckets } from './time_buckets';
import { TimeRange } from '../../../../../../../../plugins/data/public';
import { IUiSettingsClient } from '../../../../../../../../core/public';

export function toAbsoluteDates(range: TimeRange) {
const fromDate = dateMath.parse(range.from);
const toDate = dateMath.parse(range.to, { roundUp: true });

if (!fromDate || !toDate) {
return;
}

return {
from: fromDate.toDate(),
to: toDate.toDate(),
};
}

export function getCalculateAutoTimeExpression(uiSettings: IUiSettingsClient) {
return function calculateAutoTimeExpression(range: TimeRange) {
const dates = toAbsoluteDates(range);
if (!dates) {
return;
}

const buckets = new TimeBuckets({ uiSettings });

buckets.setInterval('auto');
buckets.setBounds({
min: dates.from,
max: dates.to,
});

return buckets.getInterval().expression;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@
* under the License.
*/

import dateMath from '@elastic/datemath';
import moment from 'moment';
import dateMath, { Unit } from '@elastic/datemath';

import { parseEsInterval } from '../../../core_plugins/data/public';
import { parseEsInterval } from '../../../../../../common';

const unitsDesc = dateMath.unitsDesc;
const largeMax = unitsDesc.indexOf('M');

export interface EsInterval {
expression: string;
unit: Unit;
value: number;
}

/**
* Convert a moment.duration into an es
* compatible expression, and provide
Expand All @@ -32,7 +39,7 @@ const largeMax = unitsDesc.indexOf('M');
* @param {moment.duration} duration
* @return {object}
*/
export function convertDurationToNormalizedEsInterval(duration) {
export function convertDurationToNormalizedEsInterval(duration: moment.Duration): EsInterval {
for (let i = 0; i < unitsDesc.length; i++) {
const unit = unitsDesc[i];
const val = duration.as(unit);
Expand All @@ -47,7 +54,7 @@ export function convertDurationToNormalizedEsInterval(duration) {

return {
value: val,
unit: unit,
unit,
expression: val + unit,
};
}
Expand All @@ -61,7 +68,7 @@ export function convertDurationToNormalizedEsInterval(duration) {
};
}

export function convertIntervalToEsInterval(interval) {
export function convertIntervalToEsInterval(interval: string): EsInterval {
const { value, unit } = parseEsInterval(interval);
return {
value,
Expand Down
File renamed without changes.
Loading

0 comments on commit 3905bea

Please sign in to comment.