Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up date histogram agg type. #58805

Merged
merged 13 commits into from
Mar 5, 2020
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;
lukeelmers marked this conversation as resolved.
Show resolved Hide resolved
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
Loading