add limit of 100 values when grouping by multi value fields

This commit is contained in:
alex prozorov 2025-04-11 09:51:58 +03:00
parent d9d9fba3d6
commit cdcd99443e
2 changed files with 44 additions and 11 deletions

View file

@ -17,6 +17,9 @@ export const DEFAULT_GROUP_BY_FIELD_SIZE = 10;
// https://github.com/elastic/kibana/issues/151913
export const MAX_QUERY_SIZE = 10000;
// there is known limitation for max size of runtime field which is used in the runtime_mappings script
export const MAX_RUNTIME_FIELD_SIZE = 100;
/**
* Composes grouping query and aggregations
* @param additionalFilters Global filtering applicable to the grouping component.
@ -64,7 +67,8 @@ export const getGroupingQuery = ({
script: {
source:
// when size()==0, emits a uniqueValue as the value to represent this group
"if (doc[params['selectedGroup']].size()==0) { emit(params['uniqueValue']) }" +
`if (doc[params['selectedGroup']].size()==0 || doc[params['selectedGroup']].size() > ${MAX_RUNTIME_FIELD_SIZE} ) { emit(params['uniqueValue']) }` +
// `if (doc[params['selectedGroup']].size()==0 ) { emit(params['uniqueValue']) }` +
/*
* condition to decide between joining values or flattening based on shouldFlattenMultiValueField and groupByField parameters
* if shouldFlattenMultiValueField is true, and the selectedGroup field is an array, then emit each value in the array
@ -78,7 +82,7 @@ export const getGroupingQuery = ({
* We will format into a proper array in parseGroupingQuery
*/
(shouldFlattenMultiValueField
? " else { for (def id : doc[params['selectedGroup']]) { emit(id) }}"
? ` else { int i = 0; for (def id : doc['vulnerability.id']) { if (i++ >= ${MAX_RUNTIME_FIELD_SIZE}) break; emit(id)}}`
: " else { emit(doc[params['selectedGroup']].join(params['uniqueValue']))}"),
params: {
selectedGroup: groupByField,

View file

@ -12,6 +12,7 @@ import {
isNoneGroup,
NamedAggregation,
parseGroupingQuery,
MAX_RUNTIME_FIELD_SIZE,
} from '@kbn/grouping/src';
import { useMemo } from 'react';
import {
@ -133,6 +134,42 @@ const getRuntimeMappingsByGroupField = (
return {};
};
/**
* Returns the root aggregations query for the vulnerabilities grouping
*/
const getRootAggregations = (currentSelectedGroup: string): NamedAggregation[] => [
{
...(!isNoneGroup([currentSelectedGroup]) && {
nullGroupItems: {
filter: {
bool: {
should: [
{
bool: {
must_not: {
exists: {
field: currentSelectedGroup,
},
},
},
},
{
script: {
script: {
source: `doc['${currentSelectedGroup}'].size() > ${MAX_RUNTIME_FIELD_SIZE}`,
lang: 'painless',
},
},
},
],
minimum_should_match: 1,
},
},
},
}),
},
];
/**
* Type Guard for checking if the given source is a VulnerabilitiesRootGroupingAggregation
*/
@ -205,15 +242,7 @@ export const useLatestVulnerabilitiesGrouping = ({
sort: [{ groupByField: { order: 'desc' } }],
statsAggregations: getAggregationsByGroupField(currentSelectedGroup),
runtimeMappings: getRuntimeMappingsByGroupField(currentSelectedGroup),
rootAggregations: [
{
...(!isNoneGroup([currentSelectedGroup]) && {
nullGroupItems: {
missing: { field: currentSelectedGroup },
},
}),
},
],
rootAggregations: getRootAggregations(currentSelectedGroup),
multiValueFieldsToFlatten: VULNERABILITY_GROUPING_MULTIPLE_VALUE_FIELDS,
countByKeyForMultiValueFields: EVENT_ID,
});