mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[ES|QL] Add weighted_avg
ES|QL function support (#187439)
## Summary - Adds `weighted_avg` function definition - Adds basic smoke tests ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
parent
ce4f4693f4
commit
7e04249054
3 changed files with 401 additions and 0 deletions
|
@ -264,4 +264,39 @@ export const statsAggregationFunctionDefinitions: FunctionDefinition[] = [
|
|||
`from employees | stats date = top(hire_date, 2, "asc"), double = top(salary_change, 2, "asc"),`,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'weighted_avg',
|
||||
type: 'agg',
|
||||
description: i18n.translate(
|
||||
'kbn-esql-validation-autocomplete.esql.definitions.weightedAvgDoc',
|
||||
{
|
||||
defaultMessage:
|
||||
'An aggregation that computes the weighted average of numeric values that are extracted from the aggregated documents.',
|
||||
}
|
||||
),
|
||||
supportedCommands: ['stats', 'metrics'],
|
||||
signatures: [
|
||||
{
|
||||
params: [
|
||||
{
|
||||
name: 'number',
|
||||
type: 'number',
|
||||
noNestingFunctions: true,
|
||||
optional: false,
|
||||
},
|
||||
{
|
||||
name: 'weight',
|
||||
type: 'number',
|
||||
noNestingFunctions: true,
|
||||
optional: false,
|
||||
},
|
||||
],
|
||||
returnType: 'number',
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
`from employees | stats w_avg = weighted_avg(salary, height) by languages | eval w_avg = round(w_avg)`,
|
||||
`from employees | stats w_avg_1 = weighted_avg(salary, 1), avg = avg(salary), w_avg_2 = weighted_avg(salary, height)`,
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
|
|
@ -26061,6 +26061,36 @@
|
|||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats var = top(stringField, 5, \"asc\")",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats top(stringField, 5, \"asc\")",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats top(stringField, numberField, \"asc\")",
|
||||
"error": [
|
||||
"Argument of [top] must be a constant, received [numberField]"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats top(null, null, null)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "row nullVar = null | stats top(nullVar, nullVar, nullVar)",
|
||||
"error": [
|
||||
"Argument of [top] must be a constant, received [nullVar]",
|
||||
"Argument of [top] must be a constant, received [nullVar]"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "row var = st_distance(to_cartesianpoint(\"POINT (30 10)\"), to_cartesianpoint(\"POINT (30 10)\"))",
|
||||
"error": [],
|
||||
|
@ -26159,6 +26189,184 @@
|
|||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats var = weighted_avg(numberField, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats weighted_avg(numberField, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats var = round(weighted_avg(numberField, numberField))",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats round(weighted_avg(numberField, numberField))",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats var = round(weighted_avg(numberField, numberField)) + weighted_avg(numberField, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats round(weighted_avg(numberField, numberField)) + weighted_avg(numberField, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats weighted_avg(numberField / 2, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats var0 = weighted_avg(numberField / 2, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats avg(numberField), weighted_avg(numberField / 2, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats avg(numberField), var0 = weighted_avg(numberField / 2, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats var0 = weighted_avg(numberField, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats avg(numberField), weighted_avg(numberField, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats avg(numberField), var0 = weighted_avg(numberField, numberField)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats weighted_avg(numberField, numberField) by round(numberField / 2)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats var0 = weighted_avg(numberField, numberField) by var1 = round(numberField / 2)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats avg(numberField), weighted_avg(numberField, numberField) by round(numberField / 2), ipField",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats avg(numberField), var0 = weighted_avg(numberField, numberField) by var1 = round(numberField / 2), ipField",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats avg(numberField), weighted_avg(numberField, numberField) by round(numberField / 2), numberField / 2",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats avg(numberField), var0 = weighted_avg(numberField, numberField) by var1 = round(numberField / 2), numberField / 2",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats var = weighted_avg(avg(numberField), avg(numberField))",
|
||||
"error": [
|
||||
"Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [avg(numberField)] of type [number]",
|
||||
"Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [avg(numberField)] of type [number]"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats weighted_avg(avg(numberField), avg(numberField))",
|
||||
"error": [
|
||||
"Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [avg(numberField)] of type [number]",
|
||||
"Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [avg(numberField)] of type [number]"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats weighted_avg(booleanField, booleanField)",
|
||||
"error": [
|
||||
"Argument of [weighted_avg] must be [number], found value [booleanField] type [boolean]",
|
||||
"Argument of [weighted_avg] must be [number], found value [booleanField] type [boolean]"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | sort weighted_avg(numberField, numberField)",
|
||||
"error": [
|
||||
"SORT does not support function weighted_avg"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | where weighted_avg(numberField, numberField)",
|
||||
"error": [
|
||||
"WHERE does not support function weighted_avg"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | where weighted_avg(numberField, numberField) > 0",
|
||||
"error": [
|
||||
"WHERE does not support function weighted_avg"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | eval var = weighted_avg(numberField, numberField)",
|
||||
"error": [
|
||||
"EVAL does not support function weighted_avg"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | eval var = weighted_avg(numberField, numberField) > 0",
|
||||
"error": [
|
||||
"EVAL does not support function weighted_avg"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | eval weighted_avg(numberField, numberField)",
|
||||
"error": [
|
||||
"EVAL does not support function weighted_avg"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | eval weighted_avg(numberField, numberField) > 0",
|
||||
"error": [
|
||||
"EVAL does not support function weighted_avg"
|
||||
],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "from a_index | stats weighted_avg(null, null)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "row nullVar = null | stats weighted_avg(nullVar, nullVar)",
|
||||
"error": [],
|
||||
"warning": []
|
||||
},
|
||||
{
|
||||
"query": "f",
|
||||
"error": [
|
||||
|
|
|
@ -10253,6 +10253,18 @@ describe('validation logic', () => {
|
|||
testErrorsAndWarnings('from a_index | eval top(stringField, 5, "asc") > 0', [
|
||||
'EVAL does not support function top',
|
||||
]);
|
||||
testErrorsAndWarnings('from a_index | stats var = top(stringField, 5, "asc")', []);
|
||||
testErrorsAndWarnings('from a_index | stats top(stringField, 5, "asc")', []);
|
||||
|
||||
testErrorsAndWarnings('from a_index | stats top(stringField, numberField, "asc")', [
|
||||
'Argument of [top] must be a constant, received [numberField]',
|
||||
]);
|
||||
|
||||
testErrorsAndWarnings('from a_index | stats top(null, null, null)', []);
|
||||
testErrorsAndWarnings('row nullVar = null | stats top(nullVar, nullVar, nullVar)', [
|
||||
'Argument of [top] must be a constant, received [nullVar]',
|
||||
'Argument of [top] must be a constant, received [nullVar]',
|
||||
]);
|
||||
});
|
||||
|
||||
describe('st_distance', () => {
|
||||
|
@ -10335,6 +10347,152 @@ describe('validation logic', () => {
|
|||
testErrorsAndWarnings('from a_index | eval st_distance(null, null)', []);
|
||||
testErrorsAndWarnings('row nullVar = null | eval st_distance(nullVar, nullVar)', []);
|
||||
});
|
||||
|
||||
describe('weighted_avg', () => {
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats var = weighted_avg(numberField, numberField)',
|
||||
[]
|
||||
);
|
||||
testErrorsAndWarnings('from a_index | stats weighted_avg(numberField, numberField)', []);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats var = round(weighted_avg(numberField, numberField))',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats round(weighted_avg(numberField, numberField))',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats var = round(weighted_avg(numberField, numberField)) + weighted_avg(numberField, numberField)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats round(weighted_avg(numberField, numberField)) + weighted_avg(numberField, numberField)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats weighted_avg(numberField / 2, numberField)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats var0 = weighted_avg(numberField / 2, numberField)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats avg(numberField), weighted_avg(numberField / 2, numberField)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats avg(numberField), var0 = weighted_avg(numberField / 2, numberField)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats var0 = weighted_avg(numberField, numberField)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats avg(numberField), weighted_avg(numberField, numberField)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats avg(numberField), var0 = weighted_avg(numberField, numberField)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats weighted_avg(numberField, numberField) by round(numberField / 2)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats var0 = weighted_avg(numberField, numberField) by var1 = round(numberField / 2)',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats avg(numberField), weighted_avg(numberField, numberField) by round(numberField / 2), ipField',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats avg(numberField), var0 = weighted_avg(numberField, numberField) by var1 = round(numberField / 2), ipField',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats avg(numberField), weighted_avg(numberField, numberField) by round(numberField / 2), numberField / 2',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats avg(numberField), var0 = weighted_avg(numberField, numberField) by var1 = round(numberField / 2), numberField / 2',
|
||||
[]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats var = weighted_avg(avg(numberField), avg(numberField))',
|
||||
[
|
||||
"Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [avg(numberField)] of type [number]",
|
||||
"Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [avg(numberField)] of type [number]",
|
||||
]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | stats weighted_avg(avg(numberField), avg(numberField))',
|
||||
[
|
||||
"Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [avg(numberField)] of type [number]",
|
||||
"Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [avg(numberField)] of type [number]",
|
||||
]
|
||||
);
|
||||
|
||||
testErrorsAndWarnings('from a_index | stats weighted_avg(booleanField, booleanField)', [
|
||||
'Argument of [weighted_avg] must be [number], found value [booleanField] type [boolean]',
|
||||
'Argument of [weighted_avg] must be [number], found value [booleanField] type [boolean]',
|
||||
]);
|
||||
|
||||
testErrorsAndWarnings('from a_index | sort weighted_avg(numberField, numberField)', [
|
||||
'SORT does not support function weighted_avg',
|
||||
]);
|
||||
|
||||
testErrorsAndWarnings('from a_index | where weighted_avg(numberField, numberField)', [
|
||||
'WHERE does not support function weighted_avg',
|
||||
]);
|
||||
|
||||
testErrorsAndWarnings('from a_index | where weighted_avg(numberField, numberField) > 0', [
|
||||
'WHERE does not support function weighted_avg',
|
||||
]);
|
||||
|
||||
testErrorsAndWarnings('from a_index | eval var = weighted_avg(numberField, numberField)', [
|
||||
'EVAL does not support function weighted_avg',
|
||||
]);
|
||||
|
||||
testErrorsAndWarnings(
|
||||
'from a_index | eval var = weighted_avg(numberField, numberField) > 0',
|
||||
['EVAL does not support function weighted_avg']
|
||||
);
|
||||
|
||||
testErrorsAndWarnings('from a_index | eval weighted_avg(numberField, numberField)', [
|
||||
'EVAL does not support function weighted_avg',
|
||||
]);
|
||||
|
||||
testErrorsAndWarnings('from a_index | eval weighted_avg(numberField, numberField) > 0', [
|
||||
'EVAL does not support function weighted_avg',
|
||||
]);
|
||||
|
||||
testErrorsAndWarnings('from a_index | stats weighted_avg(null, null)', []);
|
||||
testErrorsAndWarnings('row nullVar = null | stats weighted_avg(nullVar, nullVar)', []);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue