Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ML] Explain Log Rate Spikes: add main chart sync on row hover at group level #141138

Merged
38 changes: 33 additions & 5 deletions x-pack/plugins/aiops/public/application/utils/query_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { Query } from '@kbn/es-query';
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
import type { ChangePoint } from '@kbn/ml-agg-utils';
import type { GroupTableItem } from '../../components/spike_analysis_table/spike_analysis_table_groups';

/*
* Contains utility functions for building and processing queries.
Expand All @@ -29,7 +30,8 @@ export function buildBaseFilterCriteria(
latestMs?: number,
query?: Query['query'],
selectedChangePoint?: ChangePoint,
includeSelectedChangePoint = true
includeSelectedChangePoint = true,
selectedGroup?: GroupTableItem | null
): estypes.QueryDslQueryContainer[] {
const filterCriteria = [];
if (timeFieldName && earliestMs && latestMs) {
Expand All @@ -48,10 +50,24 @@ export function buildBaseFilterCriteria(
filterCriteria.push(query);
}

if (selectedChangePoint && includeSelectedChangePoint) {
filterCriteria.push({
term: { [selectedChangePoint.fieldName]: selectedChangePoint.fieldValue },
});
const groupFilter = [];
if (selectedGroup) {
const allItems = { ...selectedGroup.group, ...selectedGroup.repeatedValues };
for (const fieldName in allItems) {
if (allItems.hasOwnProperty(fieldName)) {
groupFilter.push({ term: { [fieldName]: allItems[fieldName] } });
}
}
}

if (includeSelectedChangePoint) {
if (selectedChangePoint) {
filterCriteria.push({
term: { [selectedChangePoint.fieldName]: selectedChangePoint.fieldValue },
});
} else if (selectedGroup) {
filterCriteria.push(...groupFilter);
}
} else if (selectedChangePoint && !includeSelectedChangePoint) {
filterCriteria.push({
bool: {
Expand All @@ -62,6 +78,18 @@ export function buildBaseFilterCriteria(
],
},
});
} else if (selectedGroup && !includeSelectedChangePoint) {
filterCriteria.push({
bool: {
must_not: [
{
bool: {
filter: [...groupFilter],
},
},
],
},
});
}

return filterCriteria;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import type { ApiExplainLogRateSpikes } from '../../../common/api';

import { SpikeAnalysisGroupsTable } from '../spike_analysis_table';
import { SpikeAnalysisTable } from '../spike_analysis_table';
import { GroupTableItem } from '../spike_analysis_table/spike_analysis_table_groups';

const groupResultsMessage = i18n.translate(
'xpack.aiops.spikeAnalysisTable.groupedSwitchLabel.groupResults',
Expand All @@ -56,6 +57,7 @@ interface ExplainLogRateSpikesAnalysisProps {
onPinnedChangePoint?: (changePoint: ChangePoint | null) => void;
onSelectedChangePoint?: (changePoint: ChangePoint | null) => void;
selectedChangePoint?: ChangePoint;
onSelectedGroup?: (group: GroupTableItem | null) => void;
}

export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps> = ({
Expand All @@ -67,6 +69,7 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
onPinnedChangePoint,
onSelectedChangePoint,
selectedChangePoint,
onSelectedGroup,
}) => {
const { http } = useAiopsAppContext();
const basePath = http.basePath.get() ?? '';
Expand Down Expand Up @@ -249,6 +252,7 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
onPinnedChangePoint={onPinnedChangePoint}
onSelectedChangePoint={onSelectedChangePoint}
selectedChangePoint={selectedChangePoint}
onSelectedGroup={onSelectedGroup}
dataViewId={dataView.id}
/>
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { SearchPanel } from '../search_panel';

import { restorableDefaults } from './explain_log_rate_spikes_app_state';
import { ExplainLogRateSpikesAnalysis } from './explain_log_rate_spikes_analysis';
import type { GroupTableItem } from '../spike_analysis_table/spike_analysis_table_groups';

// TODO port to `@emotion/react` once `useEuiBreakpoint` is available https://github.com/elastic/eui/pull/6057
import './explain_log_rate_spikes_page.scss';
Expand Down Expand Up @@ -94,6 +95,7 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({

const [pinnedChangePoint, setPinnedChangePoint] = useState<ChangePoint | null>(null);
const [selectedChangePoint, setSelectedChangePoint] = useState<ChangePoint | null>(null);
const [selectedGroup, setSelectedGroup] = useState<GroupTableItem | null>(null);

// If a row is pinned, still overrule with a potentially hovered row.
const currentSelectedChangePoint = useMemo(() => {
Expand All @@ -116,7 +118,9 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
{ currentDataView: dataView, currentSavedSearch },
aiopsListState,
setGlobalState,
currentSelectedChangePoint
currentSelectedChangePoint,
undefined,
selectedGroup
);

const { totalCount, documentCountStats, documentCountStatsCompare } = documentStats;
Expand Down Expand Up @@ -167,6 +171,7 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
setWindowParameters(undefined);
setPinnedChangePoint(null);
setSelectedChangePoint(null);
setSelectedGroup(null);
}

return (
Expand Down Expand Up @@ -225,7 +230,9 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
clearSelectionHandler={clearSelection}
documentCountStats={documentCountStats}
documentCountStatsSplit={
currentSelectedChangePoint ? documentCountStatsCompare : undefined
currentSelectedChangePoint || selectedGroup
? documentCountStatsCompare
: undefined
}
totalCount={totalCount}
changePoint={currentSelectedChangePoint}
Expand All @@ -246,6 +253,7 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
onPinnedChangePoint={setPinnedChangePoint}
onSelectedChangePoint={setSelectedChangePoint}
selectedChangePoint={currentSelectedChangePoint}
onSelectedGroup={setSelectedGroup}
/>
)}
{windowParameters === undefined && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ const viewInDiscoverMessage = i18n.translate(
}
);

interface GroupTableItem {
id: string;
export interface GroupTableItem {
id: number;
docCount: number;
pValue: number | null;
group: Record<string, string | number>;
Expand All @@ -67,6 +67,7 @@ interface SpikeAnalysisTableProps {
onPinnedChangePoint?: (changePoint: ChangePoint | null) => void;
onSelectedChangePoint?: (changePoint: ChangePoint | null) => void;
selectedChangePoint?: ChangePoint;
onSelectedGroup?: (group: GroupTableItem | null) => void;
}

export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
Expand All @@ -77,6 +78,7 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
onPinnedChangePoint,
onSelectedChangePoint,
selectedChangePoint,
onSelectedGroup,
}) => {
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(10);
Expand Down Expand Up @@ -316,6 +318,7 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
/>
),
sortable: false,
valign: 'top',
},
{
'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnDocCount',
Expand Down Expand Up @@ -470,6 +473,16 @@ export const SpikeAnalysisGroupsTable: FC<SpikeAnalysisTableProps> = ({
rowProps={(group) => {
return {
'data-test-subj': `aiopsSpikeAnalysisGroupsTableRow row-${group.id}`,
onMouseEnter: () => {
if (onSelectedGroup) {
onSelectedGroup(group);
}
},
onMouseLeave: () => {
if (onSelectedGroup) {
onSelectedGroup(null);
}
},
};
}}
/>
Expand Down
6 changes: 5 additions & 1 deletion x-pack/plugins/aiops/public/get_document_stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type { ChangePoint } from '@kbn/ml-agg-utils';
import type { Query } from '@kbn/es-query';

import { buildBaseFilterCriteria } from './application/utils/query_utils';
import { GroupTableItem } from './components/spike_analysis_table/spike_analysis_table_groups';

export interface DocumentCountStats {
interval?: number;
Expand All @@ -34,6 +35,7 @@ export interface DocumentStatsSearchStrategyParams {
fieldsToFetch?: string[];
selectedChangePoint?: ChangePoint;
includeSelectedChangePoint?: boolean;
selectedGroup?: GroupTableItem | null;
}

export const getDocumentCountStatsRequest = (params: DocumentStatsSearchStrategyParams) => {
Expand All @@ -48,6 +50,7 @@ export const getDocumentCountStatsRequest = (params: DocumentStatsSearchStrategy
fieldsToFetch,
selectedChangePoint,
includeSelectedChangePoint,
selectedGroup,
} = params;

const size = 0;
Expand All @@ -57,7 +60,8 @@ export const getDocumentCountStatsRequest = (params: DocumentStatsSearchStrategy
latestMs,
searchQuery,
selectedChangePoint,
includeSelectedChangePoint
includeSelectedChangePoint,
selectedGroup
);

// Don't use the sampler aggregation as this can lead to some potentially
Expand Down
24 changes: 18 additions & 6 deletions x-pack/plugins/aiops/public/hooks/use_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
import { useTimefilter } from './use_time_filter';
import { useDocumentCountStats } from './use_document_count_stats';
import type { Dictionary } from './use_url_state';
import type { GroupTableItem } from '../components/spike_analysis_table/spike_analysis_table_groups';

const DEFAULT_BAR_TARGET = 75;

Expand All @@ -39,7 +40,8 @@ export const useData = (
aiopsListState: AiOpsIndexBasedAppState,
onUpdate: (params: Dictionary<unknown>) => void,
selectedChangePoint?: ChangePoint,
barTarget: number = DEFAULT_BAR_TARGET
barTarget: number = DEFAULT_BAR_TARGET,
selectedGroup?: GroupTableItem | null
) => {
const {
uiSettings,
Expand Down Expand Up @@ -109,15 +111,25 @@ export const useData = (

const overallStatsRequest = useMemo(() => {
return fieldStatsRequest
? { ...fieldStatsRequest, selectedChangePoint, includeSelectedChangePoint: false }
? {
...fieldStatsRequest,
selectedChangePoint,
selectedGroup,
includeSelectedChangePoint: false,
}
: undefined;
}, [fieldStatsRequest, selectedChangePoint]);
}, [fieldStatsRequest, selectedChangePoint, selectedGroup]);

const selectedChangePointStatsRequest = useMemo(() => {
return fieldStatsRequest && selectedChangePoint
? { ...fieldStatsRequest, selectedChangePoint, includeSelectedChangePoint: true }
return fieldStatsRequest && (selectedChangePoint || selectedGroup)
? {
...fieldStatsRequest,
selectedChangePoint,
selectedGroup,
includeSelectedChangePoint: true,
}
: undefined;
}, [fieldStatsRequest, selectedChangePoint]);
}, [fieldStatsRequest, selectedChangePoint, selectedGroup]);

const documentStats = useDocumentCountStats(
overallStatsRequest,
Expand Down