Transformations: Use field name matcher for finding group by fields (#104664)
Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
@@ -461,4 +461,50 @@ describe('GroupBy transformer', () => {
|
||||
expect(result[0].fields).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should match on base name if did not match on displayName', async () => {
|
||||
const testSeries = toDataFrame({
|
||||
name: 'A',
|
||||
fields: [
|
||||
{ name: 'message', type: FieldType.string, values: ['A', 'A'], config: { displayName: 'MyMessage' } },
|
||||
{ name: 'values', type: FieldType.number, values: [1, 2] },
|
||||
],
|
||||
});
|
||||
|
||||
const cfg: DataTransformerConfig<GroupByTransformerOptions> = {
|
||||
id: DataTransformerID.groupBy,
|
||||
options: {
|
||||
fields: {
|
||||
message: {
|
||||
operation: GroupByOperationID.groupBy,
|
||||
aggregations: [],
|
||||
},
|
||||
values: {
|
||||
operation: GroupByOperationID.aggregate,
|
||||
aggregations: [ReducerID.sum],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
await expect(transformDataFrame([cfg], [testSeries])).toEmitValuesWith((received) => {
|
||||
const result = received[0];
|
||||
const expected: Field[] = [
|
||||
{
|
||||
name: 'message',
|
||||
type: FieldType.string,
|
||||
values: ['A'],
|
||||
config: { displayName: 'MyMessage' },
|
||||
},
|
||||
{
|
||||
name: 'values (sum)',
|
||||
type: FieldType.number,
|
||||
values: [3],
|
||||
config: {},
|
||||
},
|
||||
];
|
||||
|
||||
expect(result[0].fields).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,6 +4,8 @@ import { getFieldDisplayName } from '../../field/fieldState';
|
||||
import { DataFrame, Field } from '../../types/dataFrame';
|
||||
import { DataTransformerInfo, TransformationApplicabilityLevels } from '../../types/transformations';
|
||||
import { getFieldTypeForReducer, reduceField, ReducerID } from '../fieldReducer';
|
||||
import { getFieldMatcher } from '../matchers';
|
||||
import { FieldMatcherID } from '../matchers/ids';
|
||||
|
||||
import { DataTransformerID } from './ids';
|
||||
import { findMaxFields } from './utils';
|
||||
@@ -57,20 +59,31 @@ export const groupByTransformer: DataTransformerInfo<GroupByTransformerOptions>
|
||||
operator: (options) => (source) =>
|
||||
source.pipe(
|
||||
map((data) => {
|
||||
const hasValidConfig = Object.keys(options.fields).find(
|
||||
(name) => options.fields[name].operation === GroupByOperationID.groupBy
|
||||
);
|
||||
const groupByFieldNames: string[] = [];
|
||||
|
||||
if (!hasValidConfig) {
|
||||
for (const [k, v] of Object.entries(options.fields)) {
|
||||
if (v.operation === GroupByOperationID.groupBy) {
|
||||
groupByFieldNames.push(k);
|
||||
}
|
||||
}
|
||||
|
||||
if (groupByFieldNames.length === 0) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const matcher = getFieldMatcher({
|
||||
id: FieldMatcherID.byNames,
|
||||
options: { names: groupByFieldNames },
|
||||
});
|
||||
|
||||
const processed: DataFrame[] = [];
|
||||
|
||||
for (const frame of data) {
|
||||
// Create a list of fields to group on
|
||||
// If there are none we skip the rest
|
||||
const groupByFields: Field[] = frame.fields.filter((field) => shouldGroupOnField(field, options));
|
||||
|
||||
const groupByFields: Field[] = frame.fields.filter((field) => matcher(field, frame, data));
|
||||
|
||||
if (groupByFields.length === 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -131,11 +144,6 @@ export const groupByTransformer: DataTransformerInfo<GroupByTransformerOptions>
|
||||
),
|
||||
};
|
||||
|
||||
const shouldGroupOnField = (field: Field, options: GroupByTransformerOptions): boolean => {
|
||||
const fieldName = getFieldDisplayName(field);
|
||||
return options?.fields[fieldName]?.operation === GroupByOperationID.groupBy;
|
||||
};
|
||||
|
||||
const shouldCalculateField = (field: Field, options: GroupByTransformerOptions): boolean => {
|
||||
const fieldName = getFieldDisplayName(field);
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user