Skip to content

Commit

Permalink
[ML] DF Analytics Outlier detection results: improve handling of text…
Browse files Browse the repository at this point in the history
… fields (elastic#55002)

* add keyword suffix to fieldName when both text and keyword

* update exploration jest test
  • Loading branch information
alvarezmelissa87 authored and jkelastic committed Jan 17, 2020
1 parent 3e76e0f commit b92b2d2
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import { shallow } from 'enzyme';
import React from 'react';
import { DATA_FRAME_TASK_STATE } from '../../../analytics_management/components/analytics_list/common';
import { KibanaContext } from '../../../../../contexts/kibana';
import { kibanaContextValueMock } from '../../../../../contexts/kibana/__mocks__/kibana_context_value';

jest.mock('../../../../../contexts/ui/use_ui_chrome_context');
jest.mock('ui/new_platform');
Expand All @@ -22,7 +24,9 @@ jest.mock('react', () => {
describe('Data Frame Analytics: <Exploration />', () => {
test('Minimal initialization', () => {
const wrapper = shallow(
<Exploration jobId="the-job-id" jobStatus={DATA_FRAME_TASK_STATE.STOPPED} />
<KibanaContext.Provider value={kibanaContextValueMock}>
<Exploration jobId="the-job-id" jobStatus={DATA_FRAME_TASK_STATE.STOPPED} />
</KibanaContext.Provider>
);
// Without the jobConfig being loaded, the component will just return empty.
expect(wrapper.text()).toMatch('');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
SEARCH_SIZE,
defaultSearchQuery,
} from '../../../../common';
import { isKeywordAndTextType } from '../../../../common/fields';

import { getOutlierScoreFieldName } from './common';
import { useExploreData, TableItem } from './use_explore_data';
Expand All @@ -64,6 +65,10 @@ import {
} from '../../../analytics_management/components/analytics_list/common';
import { getTaskStateBadge } from '../../../analytics_management/components/analytics_list/columns';
import { SavedSearchQuery } from '../../../../../contexts/kibana';
import { getIndexPatternIdFromName } from '../../../../../util/index_utils';
import { IIndexPattern } from '../../../../../../../../../../../src/plugins/data/common/index_patterns';
import { newJobCapsService } from '../../../../../services/new_job_capabilities_service';
import { useKibanaContext } from '../../../../../contexts/kibana';

const FEATURE_INFLUENCE = 'feature_influence';

Expand Down Expand Up @@ -110,6 +115,19 @@ export const Exploration: FC<Props> = React.memo(({ jobId, jobStatus }) => {
const [searchError, setSearchError] = useState<any>(undefined);
const [searchString, setSearchString] = useState<string | undefined>(undefined);

const kibanaContext = useKibanaContext();

const initializeJobCapsService = async () => {
if (jobConfig !== undefined) {
const sourceIndex = jobConfig.source.index[0];
const indexPatternId = getIndexPatternIdFromName(sourceIndex) || sourceIndex;
const indexPattern: IIndexPattern = await kibanaContext.indexPatterns.get(indexPatternId);
if (indexPattern !== undefined) {
await newJobCapsService.initializeFromIndexPattern(indexPattern, false, false);
}
}
};

useEffect(() => {
(async function() {
const analyticsConfigs: GetDataFrameAnalyticsResponse = await ml.dataFrameAnalytics.getDataFrameAnalytics(
Expand All @@ -124,6 +142,10 @@ export const Exploration: FC<Props> = React.memo(({ jobId, jobStatus }) => {
})();
}, []);

useEffect(() => {
initializeJobCapsService();
}, [jobConfig && jobConfig.id]);

const [selectedFields, setSelectedFields] = useState([] as EsFieldName[]);
const [isColumnsPopoverVisible, setColumnsPopoverVisible] = useState(false);

Expand Down Expand Up @@ -293,10 +315,16 @@ export const Exploration: FC<Props> = React.memo(({ jobId, jobStatus }) => {
if (jobConfig !== undefined) {
const outlierScoreFieldName = getOutlierScoreFieldName(jobConfig);
const outlierScoreFieldSelected = selectedFields.includes(outlierScoreFieldName);
let requiresKeyword = false;

const field = outlierScoreFieldSelected ? outlierScoreFieldName : selectedFields[0];
const direction = outlierScoreFieldSelected ? SORT_DIRECTION.DESC : SORT_DIRECTION.ASC;
loadExploreData({ field, direction, searchQuery });

if (outlierScoreFieldSelected === false) {
requiresKeyword = isKeywordAndTextType(field);
}

loadExploreData({ field, direction, searchQuery, requiresKeyword });
}
}, [JSON.stringify(searchQuery)]);

Expand All @@ -307,10 +335,16 @@ export const Exploration: FC<Props> = React.memo(({ jobId, jobStatus }) => {
if (jobConfig !== undefined && columns.length > 0 && !selectedFields.includes(sortField)) {
const outlierScoreFieldName = getOutlierScoreFieldName(jobConfig);
const outlierScoreFieldSelected = selectedFields.includes(outlierScoreFieldName);
let requiresKeyword = false;

const field = outlierScoreFieldSelected ? outlierScoreFieldName : selectedFields[0];
const direction = outlierScoreFieldSelected ? SORT_DIRECTION.DESC : SORT_DIRECTION.ASC;
loadExploreData({ field, direction, searchQuery });

if (outlierScoreFieldSelected === false) {
requiresKeyword = isKeywordAndTextType(field);
}

loadExploreData({ field, direction, searchQuery, requiresKeyword });
return;
}
}, [jobConfig, columns.length, sortField, sortDirection, tableItems.length]);
Expand All @@ -334,8 +368,17 @@ export const Exploration: FC<Props> = React.memo(({ jobId, jobStatus }) => {
setPageIndex(index);
setPageSize(size);

if (sort.field !== sortField || sort.direction !== sortDirection) {
loadExploreData({ ...sort, searchQuery });
if (
(sort.field !== sortField || sort.direction !== sortDirection) &&
jobConfig !== undefined
) {
const outlierScoreFieldName = getOutlierScoreFieldName(jobConfig);
let requiresKeyword = false;

if (outlierScoreFieldName !== sort.field) {
requiresKeyword = isKeywordAndTextType(sort.field);
}
loadExploreData({ ...sort, searchQuery, requiresKeyword });
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,12 @@ import {
defaultSearchQuery,
SearchQuery,
} from '../../../../common';
import { LoadExploreDataArg } from '../../../../common/analytics';

import { getOutlierScoreFieldName } from './common';
import { SavedSearchQuery } from '../../../../../contexts/kibana';

export type TableItem = Record<string, any>;

interface LoadExploreDataArg {
field: string;
direction: SortDirection;
searchQuery: SavedSearchQuery;
}

export interface UseExploreDataReturnType {
errorMessage: string;
loadExploreData: (arg: LoadExploreDataArg) => void;
Expand All @@ -55,7 +49,12 @@ export const useExploreData = (
const [sortField, setSortField] = useState<string>('');
const [sortDirection, setSortDirection] = useState<SortDirection>(SORT_DIRECTION.ASC);

const loadExploreData = async ({ field, direction, searchQuery }: LoadExploreDataArg) => {
const loadExploreData = async ({
field,
direction,
searchQuery,
requiresKeyword,
}: LoadExploreDataArg) => {
if (jobConfig !== undefined) {
setErrorMessage('');
setStatus(INDEX_STATUS.LOADING);
Expand All @@ -70,7 +69,7 @@ export const useExploreData = (
if (field !== undefined) {
body.sort = [
{
[field]: {
[`${field}${requiresKeyword ? '.keyword' : ''}`]: {
order: direction,
},
},
Expand Down

0 comments on commit b92b2d2

Please sign in to comment.