mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Security Solution: reimplement filterBrowserFieldsByFieldName (#128779)
The function filterBrowserFieldsByFieldName is being run 4+ times when loading pages in the Security app. With a large number of fields, such as is found in production environment, this function can take 10+ seconds to completed. With this implementation, it should run a bit quicker.
This commit is contained in:
parent
7d94876df4
commit
4ce6f20fec
1 changed files with 45 additions and 24 deletions
|
@ -37,42 +37,63 @@ export const getFieldCount = (category: Partial<BrowserField> | undefined): numb
|
|||
* Filters the specified `BrowserFields` to return a new collection where every
|
||||
* category contains at least one field name that matches the specified substring.
|
||||
*/
|
||||
export const filterBrowserFieldsByFieldName = ({
|
||||
export function filterBrowserFieldsByFieldName({
|
||||
browserFields,
|
||||
substring,
|
||||
}: {
|
||||
browserFields: BrowserFields;
|
||||
substring: string;
|
||||
}): BrowserFields => {
|
||||
}): BrowserFields {
|
||||
const trimmedSubstring = substring.trim();
|
||||
// an empty search param will match everything, so return the original browserFields
|
||||
if (trimmedSubstring === '') {
|
||||
return browserFields;
|
||||
}
|
||||
const result: Record<string, Partial<BrowserField>> = {};
|
||||
for (const [categoryName, categoryDescriptor] of Object.entries(browserFields)) {
|
||||
if (!categoryDescriptor.fields) {
|
||||
// ignore any category that is missing fields. This is not expected to happen.
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
// filter each category such that it only contains fields with field names
|
||||
// that contain the specified substring:
|
||||
const filteredBrowserFields: BrowserFields = Object.keys(browserFields).reduce(
|
||||
(filteredCategories, categoryId) => ({
|
||||
...filteredCategories,
|
||||
[categoryId]: {
|
||||
...browserFields[categoryId],
|
||||
fields: pickBy(
|
||||
({ name }) => name != null && name.includes(trimmedSubstring),
|
||||
browserFields[categoryId].fields
|
||||
),
|
||||
},
|
||||
}),
|
||||
{}
|
||||
);
|
||||
// keep track of whether this category had a matching field, if so, we should emit it into the result
|
||||
let hadAMatch = false;
|
||||
|
||||
// only pick non-empty categories from the filtered browser fields
|
||||
const nonEmptyCategories: BrowserFields = pickBy(
|
||||
(category) => categoryHasFields(category),
|
||||
filteredBrowserFields
|
||||
);
|
||||
// The fields that matched, for this `categoryName`
|
||||
const filteredFields: Record<string, Partial<BrowserField>> = {};
|
||||
|
||||
return nonEmptyCategories;
|
||||
};
|
||||
for (const [fieldName, fieldDescriptor] of Object.entries(categoryDescriptor.fields)) {
|
||||
// For historical reasons, we consider the name as it appears on the field descriptor, not the `fieldName` (attribute name) itself.
|
||||
// It is unclear if there is any point in continuing to do this.
|
||||
const fieldNameFromDescriptor = fieldDescriptor.name;
|
||||
|
||||
if (!fieldNameFromDescriptor) {
|
||||
// Ignore any field that is missing a name in its descriptor. This is not expected to happen.
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if this field matches (via substring comparison) the passed substring
|
||||
if (fieldNameFromDescriptor !== null && fieldNameFromDescriptor.includes(trimmedSubstring)) {
|
||||
// this field is a match, so we should emit this category into the result object.
|
||||
hadAMatch = true;
|
||||
|
||||
// emit this field
|
||||
filteredFields[fieldName] = fieldDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
if (hadAMatch) {
|
||||
// if at least one field matches, emit the category, but replace the `fields` attribute with the filtered fields
|
||||
result[categoryName] = {
|
||||
...browserFields[categoryName],
|
||||
fields: filteredFields,
|
||||
};
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the selected `BrowserFields` to return a new collection where every
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue