[ML] Explain Log Rate Spikes: Fix field candidate selection. (#147614)

The field candidate selection for Explain Log Rate Spikes was missing a
check if the supported field type is also aggregatable. For example, a
`keyword` type field could still be non-aggregatable if it was both not
indexed and `doc_values` set to `false`. Additionally, if no groups were
detected, we showed a "Try to continue analysis" button in the UI even
if the analysis was able to finish. In this PR the artificial logs dataset for functional tests was extended
to include a field like that.
This commit is contained in:
Walter Rafelsberger 2022-12-19 18:35:31 +01:00 committed by GitHub
parent b00a2643cd
commit aecad27159
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 6 deletions

View file

@ -112,8 +112,9 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
const { loaded, remainingFieldCandidates, groupsMissing } = data;
if (
(Array.isArray(remainingFieldCandidates) && remainingFieldCandidates.length > 0) ||
groupsMissing
loaded < 1 &&
((Array.isArray(remainingFieldCandidates) && remainingFieldCandidates.length > 0) ||
groupsMissing)
) {
setOverrides({ loaded, remainingFieldCandidates, changePoints: data.changePoints });
} else {

View file

@ -70,9 +70,16 @@ describe('fetch_index_info', () => {
it('returns field candidates and total hits', async () => {
const esClientFieldCapsMock = jest.fn(() => ({
fields: {
myIpFieldName: { ip: {} },
myKeywordFieldName: { keyword: {} },
myUnpopulatedKeywordFieldName: { keyword: {} },
// Should end up as a field candidate
myIpFieldName: { ip: { aggregatable: true } },
// Should end up as a field candidate
myKeywordFieldName: { keyword: { aggregatable: true } },
// Should not end up as a field candidate, it's a keyword but non-aggregatable
myKeywordFieldNameToBeIgnored: { keyword: { aggregatable: false } },
// Should not end up as a field candidate, based on this field caps result it would be
// but it will not be part of the mocked search result so will count as unpopulated.
myUnpopulatedKeywordFieldName: { keyword: { aggregatable: true } },
// Should not end up as a field candidate since fields of type number will not be considered
myNumericFieldName: { number: {} },
},
}));

View file

@ -68,9 +68,10 @@ export const fetchIndexInfo = async (
Object.entries(respMapping.fields).forEach(([key, value]) => {
const fieldTypes = Object.keys(value) as ES_FIELD_TYPES[];
const isSupportedType = fieldTypes.some((type) => SUPPORTED_ES_FIELD_TYPES.includes(type));
const isAggregatable = fieldTypes.some((type) => value[type].aggregatable);
// Check if fieldName is something we can aggregate on
if (isSupportedType) {
if (isSupportedType && isAggregatable) {
acceptableFields.add(key);
}
});

View file

@ -15,6 +15,7 @@ export interface GeneratedDoc {
url: string;
version: string;
'@timestamp': number;
should_ignore_this_field: string;
}
const REFERENCE_TS = 1669018354793;
@ -50,6 +51,7 @@ function getArtificialLogsWithSpike(index: string) {
url,
version: 'v1.0.0',
'@timestamp': ts + tsOffset,
should_ignore_this_field: 'should_ignore_this_field',
};
bulkBody.push(action);
@ -74,6 +76,7 @@ function getArtificialLogsWithSpike(index: string) {
url,
version: 'v1.0.0',
'@timestamp': DEVIATION_TS + tsOffset,
should_ignore_this_field: 'should_ignore_this_field',
});
});
});
@ -91,6 +94,7 @@ function getArtificialLogsWithSpike(index: string) {
url,
version: 'v1.0.0',
'@timestamp': DEVIATION_TS + tsOffset,
should_ignore_this_field: 'should_ignore_this_field',
});
});
});
@ -158,6 +162,7 @@ export function ExplainLogRateSpikesDataGeneratorProvider({ getService }: FtrPro
url: { type: 'keyword' },
version: { type: 'keyword' },
'@timestamp': { type: 'date' },
should_ignore_this_field: { type: 'keyword', doc_values: false, index: false },
},
},
});