mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
elastic: refactor: simplify query-type handling (#67921)
* elastic: refactor: simplify query-type handling * improved comment Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> --------- Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
This commit is contained in:
parent
1400a0a3f7
commit
903cf3e30d
@ -114,10 +114,10 @@ describe('Bucket Aggregations Reducer', () => {
|
||||
|
||||
reducerTester<ElasticsearchQuery['bucketAggs']>()
|
||||
.givenReducer(createReducer('@timestamp'), initialState)
|
||||
// If the new metric aggregation is `isSingleMetric` we should remove all bucket aggregations.
|
||||
// If the new metric aggregation is non-metric, we should remove all bucket aggregations.
|
||||
.whenActionIsDispatched(changeMetricType({ id: 'Some id', type: 'raw_data' }))
|
||||
.thenStatePredicateShouldEqual((newState) => newState?.length === 0)
|
||||
// Switching back to another aggregation that is NOT `isSingleMetric` should bring back a bucket aggregation
|
||||
// Switching back to another aggregation that is metric should bring back a bucket aggregation
|
||||
.whenActionIsDispatched(changeMetricType({ id: 'Some id', type: 'max' }))
|
||||
.thenStatePredicateShouldEqual((newState) => newState?.length === 1)
|
||||
// When none of the above is true state shouldn't change.
|
||||
|
@ -75,7 +75,7 @@ export const createReducer =
|
||||
if (changeMetricType.match(action)) {
|
||||
// If we are switching to a metric which requires the absence of bucket aggregations
|
||||
// we remove all of them.
|
||||
if (metricAggregationConfig[action.payload.type].isSingleMetric) {
|
||||
if (metricAggregationConfig[action.payload.type].impliedQueryType !== 'metrics') {
|
||||
return [];
|
||||
} else if (state!.length === 0) {
|
||||
// Else, if there are no bucket aggregations we restore a default one.
|
||||
|
@ -48,7 +48,7 @@ const getTypeOptions = (
|
||||
|
||||
return (
|
||||
Object.entries(metricAggregationConfig)
|
||||
.filter(([_, config]) => !config.isSingleMetric)
|
||||
.filter(([_, config]) => config.impliedQueryType === 'metrics')
|
||||
// Only showing metrics type supported by the version of ES.
|
||||
// if we cannot determine the version, we assume it is suitable.
|
||||
.filter(([_, { versionRange = '*' }]) => (esVersion != null ? satisfies(esVersion, versionRange) : true))
|
||||
|
@ -48,7 +48,7 @@ export const MetricAggregationsEditor = ({ nextId }: Props) => {
|
||||
>
|
||||
<MetricEditor value={metric} />
|
||||
|
||||
{!metricAggregationConfig[metric.type].isSingleMetric && index === 0 && (
|
||||
{metricAggregationConfig[metric.type].impliedQueryType === 'metrics' && index === 0 && (
|
||||
<IconButton iconName="plus" onClick={() => dispatch(addMetric(nextId))} label="add" />
|
||||
)}
|
||||
</QueryEditorRow>
|
||||
|
@ -84,7 +84,7 @@ describe('Metric Aggregations Reducer', () => {
|
||||
.thenStateShouldEqual([firstAggregation, { ...secondAggregation, type: expectedSecondAggregation.type }]);
|
||||
});
|
||||
|
||||
it('Should remove all other aggregations when the newly selected one is `isSingleMetric`', () => {
|
||||
it('Should remove all other aggregations when the newly selected one is not metric', () => {
|
||||
const firstAggregation: MetricAggregation = {
|
||||
id: '1',
|
||||
type: 'count',
|
||||
|
@ -36,9 +36,11 @@ export const reducer = (state: ElasticsearchQuery['metrics'], action: Action): E
|
||||
if (changeMetricType.match(action)) {
|
||||
return state!
|
||||
.filter((metric) =>
|
||||
// When the new metric type is `isSingleMetric` we remove all other metrics from the query
|
||||
// When the new query type is not `metrics` we remove all other metrics from the query
|
||||
// leaving only the current one.
|
||||
!!metricAggregationConfig[action.payload.type].isSingleMetric ? metric.id === action.payload.id : true
|
||||
metricAggregationConfig[action.payload.type].impliedQueryType === 'metrics'
|
||||
? true
|
||||
: metric.id === action.payload.id
|
||||
)
|
||||
.map((metric) => {
|
||||
if (metric.id !== action.payload.id) {
|
||||
|
@ -9,6 +9,7 @@ import { isMetricAggregationWithField, isPipelineAggregationWithMultipleBucketPa
|
||||
export const metricAggregationConfig: MetricsConfiguration = {
|
||||
count: {
|
||||
label: 'Count',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: false,
|
||||
isPipelineAgg: false,
|
||||
supportsMissing: false,
|
||||
@ -20,6 +21,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
avg: {
|
||||
label: 'Average',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
supportsInlineScript: true,
|
||||
supportsMissing: true,
|
||||
@ -31,6 +33,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
sum: {
|
||||
label: 'Sum',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
supportsInlineScript: true,
|
||||
supportsMissing: true,
|
||||
@ -42,6 +45,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
max: {
|
||||
label: 'Max',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
supportsInlineScript: true,
|
||||
supportsMissing: true,
|
||||
@ -53,6 +57,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
min: {
|
||||
label: 'Min',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
supportsInlineScript: true,
|
||||
supportsMissing: true,
|
||||
@ -64,6 +69,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
extended_stats: {
|
||||
label: 'Extended Stats',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
supportsMissing: true,
|
||||
supportsInlineScript: true,
|
||||
@ -80,6 +86,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
percentiles: {
|
||||
label: 'Percentiles',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
supportsMissing: true,
|
||||
supportsInlineScript: true,
|
||||
@ -95,6 +102,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
cardinality: {
|
||||
label: 'Unique Count',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
supportsMissing: true,
|
||||
isPipelineAgg: false,
|
||||
@ -108,6 +116,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
// deprecated in 6.4.0, removed in 8.0.0,
|
||||
// recommended replacement is moving_fn
|
||||
label: 'Moving Average',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
isPipelineAgg: true,
|
||||
versionRange: '<8.0.0',
|
||||
@ -126,6 +135,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
moving_fn: {
|
||||
// TODO: Check this
|
||||
label: 'Moving Function',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
isPipelineAgg: true,
|
||||
supportsMultipleBucketPaths: false,
|
||||
@ -137,6 +147,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
derivative: {
|
||||
label: 'Derivative',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
isPipelineAgg: true,
|
||||
supportsMissing: false,
|
||||
@ -148,6 +159,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
serial_diff: {
|
||||
label: 'Serial Difference',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
isPipelineAgg: true,
|
||||
supportsMissing: false,
|
||||
@ -163,6 +175,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
cumulative_sum: {
|
||||
label: 'Cumulative Sum',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
isPipelineAgg: true,
|
||||
supportsMissing: false,
|
||||
@ -174,6 +187,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
bucket_script: {
|
||||
label: 'Bucket Script',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: false,
|
||||
isPipelineAgg: true,
|
||||
supportsMissing: false,
|
||||
@ -188,7 +202,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
raw_document: {
|
||||
label: 'Raw Document (deprecated)',
|
||||
requiresField: false,
|
||||
isSingleMetric: true,
|
||||
impliedQueryType: 'raw_document',
|
||||
isPipelineAgg: false,
|
||||
supportsMissing: false,
|
||||
supportsMultipleBucketPaths: false,
|
||||
@ -204,7 +218,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
raw_data: {
|
||||
label: 'Raw Data',
|
||||
requiresField: false,
|
||||
isSingleMetric: true,
|
||||
impliedQueryType: 'raw_data',
|
||||
isPipelineAgg: false,
|
||||
supportsMissing: false,
|
||||
supportsMultipleBucketPaths: false,
|
||||
@ -224,7 +238,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
supportsMissing: false,
|
||||
supportsMultipleBucketPaths: false,
|
||||
hasSettings: true,
|
||||
isSingleMetric: true,
|
||||
impliedQueryType: 'logs',
|
||||
supportsInlineScript: false,
|
||||
hasMeta: false,
|
||||
defaults: {
|
||||
@ -235,6 +249,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
top_metrics: {
|
||||
label: 'Top Metrics',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: false,
|
||||
isPipelineAgg: false,
|
||||
supportsMissing: false,
|
||||
@ -250,6 +265,7 @@ export const metricAggregationConfig: MetricsConfiguration = {
|
||||
},
|
||||
rate: {
|
||||
label: 'Rate',
|
||||
impliedQueryType: 'metrics',
|
||||
requiresField: true,
|
||||
isPipelineAgg: false,
|
||||
supportsMissing: false,
|
||||
|
@ -4,12 +4,11 @@ import { SelectableValue } from '@grafana/data';
|
||||
import { RadioButtonGroup } from '@grafana/ui';
|
||||
|
||||
import { useDispatch } from '../../hooks/useStatelessReducer';
|
||||
import { MetricAggregation } from '../../types';
|
||||
import { MetricAggregation, QueryType } from '../../types';
|
||||
|
||||
import { useQuery } from './ElasticsearchQueryContext';
|
||||
import { changeMetricType } from './MetricAggregationsEditor/state/actions';
|
||||
|
||||
type QueryType = 'metrics' | 'logs' | 'raw_data' | 'raw_document';
|
||||
import { metricAggregationConfig } from './MetricAggregationsEditor/utils';
|
||||
|
||||
const OPTIONS: Array<SelectableValue<QueryType>> = [
|
||||
{ value: 'metrics', label: 'Metrics' },
|
||||
@ -18,17 +17,6 @@ const OPTIONS: Array<SelectableValue<QueryType>> = [
|
||||
{ value: 'raw_document', label: 'Raw Document' },
|
||||
];
|
||||
|
||||
function metricTypeToQueryType(type: MetricAggregation['type']): QueryType {
|
||||
switch (type) {
|
||||
case 'logs':
|
||||
case 'raw_data':
|
||||
case 'raw_document':
|
||||
return type;
|
||||
default:
|
||||
return 'metrics';
|
||||
}
|
||||
}
|
||||
|
||||
function queryTypeToMetricType(type: QueryType): MetricAggregation['type'] {
|
||||
switch (type) {
|
||||
case 'logs':
|
||||
@ -54,7 +42,7 @@ export const QueryTypeSelector = () => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const queryType = metricTypeToQueryType(firstMetric.type);
|
||||
const queryType = metricAggregationConfig[firstMetric.type].impliedQueryType;
|
||||
|
||||
const onChange = (newQueryType: QueryType) => {
|
||||
dispatch(changeMetricType({ id: firstMetric.id, type: queryTypeToMetricType(newQueryType) }));
|
||||
|
@ -104,7 +104,7 @@ const QueryEditorForm = ({ value }: Props) => {
|
||||
const isTimeSeriesQuery = value?.bucketAggs?.slice(-1)[0]?.type === 'date_histogram';
|
||||
|
||||
const showBucketAggregationsEditor = value.metrics?.every(
|
||||
(metric) => !metricAggregationConfig[metric.type].isSingleMetric
|
||||
(metric) => metricAggregationConfig[metric.type].impliedQueryType === 'metrics'
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -65,6 +65,8 @@ export interface ElasticsearchOptions extends DataSourceJsonData {
|
||||
index?: string;
|
||||
}
|
||||
|
||||
export type QueryType = 'metrics' | 'logs' | 'raw_data' | 'raw_document';
|
||||
|
||||
interface MetricConfiguration<T extends MetricAggregationType> {
|
||||
label: string;
|
||||
requiresField: boolean;
|
||||
@ -77,7 +79,7 @@ interface MetricConfiguration<T extends MetricAggregationType> {
|
||||
*/
|
||||
versionRange?: string;
|
||||
supportsMultipleBucketPaths: boolean;
|
||||
isSingleMetric?: boolean;
|
||||
impliedQueryType: QueryType;
|
||||
hasSettings: boolean;
|
||||
hasMeta: boolean;
|
||||
defaults: Omit<Extract<MetricAggregation, { type: T }>, 'id' | 'type'>;
|
||||
|
Loading…
Reference in New Issue
Block a user