Skip to content

Commit 1f10007

Browse files
authored
Enable shingle in HCAD (opensearch-project#71)
Previously, we hardcoded HCAD (including real-time and historical) shingle size to be one due to time constraints when releasing HCAD. This PR enabled shingling in HCAD on the frontend (backend PR: opensearch-project/anomaly-detection#187). Specifically, after this PR * both single-stream and HCAD detectors have a default shingle size of 8. * no special handling of HCAD detectors' shingle size. Testing done: 1. unit tests and cypress tests pass. 2. Manual testing to verify HCAD real-time and historical tasks use shingle eight by default and can use customized size. 3. Manual testing to verify preview uses shingle eight by default and can use the customized size.
1 parent eae1c19 commit 1f10007

File tree

13 files changed

+22
-60
lines changed

13 files changed

+22
-60
lines changed

public/pages/ConfigureModel/components/CategoryField/CategoryField.tsx

+1-18
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,7 @@ import {
3939
} from '@elastic/eui';
4040
import { Field, FieldProps, FormikProps } from 'formik';
4141
import { get, isEmpty } from 'lodash';
42-
import {
43-
MULTI_ENTITY_SHINGLE_SIZE,
44-
BASE_DOCS_LINK,
45-
} from '../../../../utils/constants';
42+
import { BASE_DOCS_LINK } from '../../../../utils/constants';
4643
import React, { useState, useEffect } from 'react';
4744
import ContentPanel from '../../../../components/ContentPanel/ContentPanel';
4845
import {
@@ -58,7 +55,6 @@ interface CategoryFieldProps {
5855
categoryFieldOptions: string[];
5956
setIsHCDetector(isHCDetector: boolean): void;
6057
isLoading: boolean;
61-
originalShingleSize: number;
6258
formikProps: FormikProps<ModelConfigurationFormikValues>;
6359
}
6460

@@ -129,10 +125,6 @@ export function CategoryField(props: CategoryFieldProps) {
129125
if (enabled) {
130126
props.setIsHCDetector(false);
131127
form.setFieldValue('categoryField', []);
132-
form.setFieldValue(
133-
'shingleSize',
134-
props.originalShingleSize
135-
);
136128
}
137129
setEnabled(!enabled);
138130
}}
@@ -159,18 +151,9 @@ export function CategoryField(props: CategoryFieldProps) {
159151
if (!isEmpty(selection)) {
160152
if (selection.length <= 2) {
161153
form.setFieldValue('categoryField', selection);
162-
form.setFieldValue(
163-
'shingleSize',
164-
MULTI_ENTITY_SHINGLE_SIZE
165-
);
166154
}
167155
} else {
168156
form.setFieldValue('categoryField', []);
169-
170-
form.setFieldValue(
171-
'shingleSize',
172-
props.originalShingleSize
173-
);
174157
}
175158
}}
176159
selectedOptions={

public/pages/ConfigureModel/components/CategoryField/__tests__/CategoryField.test.tsx

-5
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ describe('<CategoryField /> spec', () => {
4949
return;
5050
}}
5151
isLoading={false}
52-
originalShingleSize={1}
5352
formikProps={{
5453
values: {
5554
categoryFieldEnabled: false,
@@ -91,7 +90,6 @@ describe('<CategoryField /> spec', () => {
9190
return;
9291
}}
9392
isLoading={false}
94-
originalShingleSize={1}
9593
formikProps={{
9694
values: {
9795
categoryFieldEnabled: true,
@@ -130,7 +128,6 @@ describe('<CategoryField /> spec', () => {
130128
return;
131129
}}
132130
isLoading={false}
133-
originalShingleSize={1}
134131
formikProps={{
135132
values: {
136133
categoryFieldEnabled: true,
@@ -166,7 +163,6 @@ describe('<CategoryField /> spec', () => {
166163
return;
167164
}}
168165
isLoading={true}
169-
originalShingleSize={1}
170166
formikProps={{
171167
values: {
172168
categoryFieldEnabled: true,
@@ -201,7 +197,6 @@ describe('<CategoryField /> spec', () => {
201197
return;
202198
}}
203199
isLoading={false}
204-
originalShingleSize={1}
205200
formikProps={{
206201
values: {
207202
categoryFieldEnabled: true,

public/pages/ConfigureModel/containers/ConfigureModel.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ export function ConfigureModel(props: ConfigureModelProps) {
102102
const isLoading = useSelector(
103103
(state: AppState) => state.opensearch.requesting
104104
);
105-
const originalShingleSize = getShingleSizeFromObject(detector, isHCDetector);
106105

107106
// Jump to top of page on first load
108107
useEffect(() => {
@@ -277,7 +276,6 @@ export function ConfigureModel(props: ConfigureModelProps) {
277276
categoryFieldOptions={getCategoryFields(indexDataTypes)}
278277
setIsHCDetector={setIsHCDetector}
279278
isLoading={isLoading}
280-
originalShingleSize={originalShingleSize}
281279
formikProps={formikProps}
282280
/>
283281
<EuiSpacer />

public/pages/ConfigureModel/utils/constants.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@ import {
2929
ModelConfigurationFormikValues,
3030
FeaturesFormikValues,
3131
} from '../../ConfigureModel/models/interfaces';
32+
import { DEFAULT_SHINGLE_SIZE } from '../../../utils/constants';
3233

3334
export const INITIAL_MODEL_CONFIGURATION_VALUES: ModelConfigurationFormikValues = {
3435
featureList: [],
3536
categoryFieldEnabled: false,
3637
categoryField: [],
37-
shingleSize: 4,
38+
shingleSize: DEFAULT_SHINGLE_SIZE,
3839
};
3940

4041
export const INITIAL_FEATURE_VALUES: FeaturesFormikValues = {

public/pages/ConfigureModel/utils/helpers.ts

+5-16
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@
2424
* permissions and limitations under the License.
2525
*/
2626

27-
import {
28-
DATA_TYPES,
29-
MULTI_ENTITY_SHINGLE_SIZE,
30-
SINGLE_ENTITY_SHINGLE_SIZE,
31-
} from '../../../utils/constants';
27+
import { DATA_TYPES, DEFAULT_SHINGLE_SIZE } from '../../../utils/constants';
3228
import {
3329
FEATURE_TYPE,
3430
FeatureAttributes,
@@ -222,15 +218,8 @@ export const getCategoryFields = (dataTypes: DataTypes) => {
222218
return keywordFields.concat(ipFields);
223219
};
224220

225-
export const getShingleSizeFromObject = (
226-
obj: object,
227-
isHCDetector: boolean
228-
) => {
229-
return get(
230-
obj,
231-
'shingleSize',
232-
isHCDetector ? MULTI_ENTITY_SHINGLE_SIZE : SINGLE_ENTITY_SHINGLE_SIZE
233-
);
221+
export const getShingleSizeFromObject = (obj: object) => {
222+
return get(obj, 'shingleSize', DEFAULT_SHINGLE_SIZE);
234223
};
235224

236225
export function clearModelConfiguration(ad: Detector): Detector {
@@ -242,7 +231,7 @@ export function clearModelConfiguration(ad: Detector): Detector {
242231
features: {},
243232
},
244233
categoryField: undefined,
245-
shingleSize: SINGLE_ENTITY_SHINGLE_SIZE,
234+
shingleSize: DEFAULT_SHINGLE_SIZE,
246235
};
247236
}
248237

@@ -258,7 +247,7 @@ export function modelConfigurationToFormik(
258247
featureList: featuresToFormik(detector),
259248
categoryFieldEnabled: !isEmpty(get(detector, 'categoryField', [])),
260249
categoryField: get(detector, 'categoryField', []),
261-
shingleSize: get(detector, 'shingleSize', 4),
250+
shingleSize: get(detector, 'shingleSize', DEFAULT_SHINGLE_SIZE),
262251
};
263252
}
264253

public/pages/DefineDetector/utils/helpers.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
formikToIndices,
3838
formikToFilterQuery,
3939
} from '../../ReviewAndCreate/utils/helpers';
40-
import { SINGLE_ENTITY_SHINGLE_SIZE } from '../../../utils/constants';
40+
import { DEFAULT_SHINGLE_SIZE } from '../../../utils/constants';
4141

4242
export function detectorDefinitionToFormik(
4343
ad: Detector
@@ -149,6 +149,6 @@ export function clearModelConfiguration(ad: Detector): Detector {
149149
features: {},
150150
},
151151
categoryField: undefined,
152-
shingleSize: SINGLE_ENTITY_SHINGLE_SIZE,
152+
shingleSize: DEFAULT_SHINGLE_SIZE,
153153
};
154154
}

public/pages/DetectorConfig/containers/Features.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,7 @@ export const Features = (props: FeaturesProps) => {
105105
return sorted;
106106
};
107107
const featureAttributes = get(props.detector, 'featureAttributes', []);
108-
const isHCDetector = !isEmpty(get(props.detector, 'categoryField', []));
109-
const shingleSize = getShingleSizeFromObject(props.detector, isHCDetector);
108+
const shingleSize = getShingleSizeFromObject(props.detector);
110109

111110
const sorting = {
112111
sort: {

public/pages/DetectorResults/utils/utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
NO_DATA_IN_WINDOW_ERROR_MESSAGE,
3030
NO_RCF_MODEL_ERROR_MESSAGE,
3131
} from './constants';
32-
import { SINGLE_ENTITY_SHINGLE_SIZE } from '../../../utils/constants';
32+
import { DEFAULT_SHINGLE_SIZE } from '../../../utils/constants';
3333
import { DETECTOR_STATE } from '../../../../server/utils/constants';
3434
import moment, { Moment } from 'moment';
3535
import { get } from 'lodash';
@@ -63,7 +63,7 @@ const isDetectorInitOverTime = (currentTime: Moment, detector: Detector) => {
6363
//@ts-ignore
6464
currentTime
6565
.subtract(
66-
get(detector, 'shingleSize', SINGLE_ENTITY_SHINGLE_SIZE) *
66+
get(detector, 'shingleSize', DEFAULT_SHINGLE_SIZE) *
6767
detector.detectionInterval.period.interval,
6868
detector.detectionInterval.period.unit.toLowerCase()
6969
)

public/pages/ReviewAndCreate/components/ModelConfigurationFields/ModelConfigurationFields.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import {
3030
FEATURE_TYPE,
3131
FeatureAttributes,
3232
} from '../../../../models/interfaces';
33-
import { get, isEmpty, sortBy } from 'lodash';
33+
import { get, sortBy } from 'lodash';
3434
import ContentPanel from '../../../../components/ContentPanel/ContentPanel';
3535
import { CodeModal } from '../../../../components/CodeModal/CodeModal';
3636
import { AdditionalSettings } from '../AdditionalSettings/AdditionalSettings';
@@ -100,8 +100,7 @@ export const ModelConfigurationFields = (
100100
return sorted;
101101
};
102102
const featureAttributes = get(props.detector, 'featureAttributes', []);
103-
const isHCDetector = !isEmpty(get(props.detector, 'categoryField', []));
104-
const shingleSize = getShingleSizeFromObject(props.detector, isHCDetector);
103+
const shingleSize = getShingleSizeFromObject(props.detector);
105104

106105
const sorting = {
107106
sort: {

public/pages/ReviewAndCreate/containers/__tests__/__snapshots__/ReviewAndCreate.test.tsx.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ exports[`<ReviewAndCreate /> spec renders the component 1`] = `
486486
<span
487487
class="euiTableCellContent__text"
488488
>
489-
4
489+
8
490490
</span>
491491
</div>
492492
</td>

public/pages/ReviewAndCreate/utils/__tests__/helpers.test.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
*/
2626

2727
import { INITIAL_DETECTOR_DEFINITION_VALUES } from '../../../DefineDetector/utils/constants';
28-
import { SINGLE_ENTITY_SHINGLE_SIZE } from '../../../../utils/constants';
28+
import { DEFAULT_SHINGLE_SIZE } from '../../../../utils/constants';
2929
import { getRandomDetector } from '../../../../redux/reducers/__tests__/utils';
3030
import { formikToDetector, formikToFilterQuery } from '../../utils/helpers';
3131
import {
@@ -56,7 +56,7 @@ describe('formikToDetector', () => {
5656
featureList: [],
5757
categoryFieldEnabled: false,
5858
categoryField: [],
59-
shingleSize: SINGLE_ENTITY_SHINGLE_SIZE,
59+
shingleSize: DEFAULT_SHINGLE_SIZE,
6060
realTime: false,
6161
historical: false,
6262
startTime: undefined,
@@ -101,7 +101,7 @@ describe('formikToDetector', () => {
101101
unit: UNITS.MINUTES,
102102
},
103103
},
104-
shingleSize: SINGLE_ENTITY_SHINGLE_SIZE,
104+
shingleSize: DEFAULT_SHINGLE_SIZE,
105105
categoryField: undefined,
106106
});
107107
});

public/redux/reducers/__tests__/utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
} from '../../../models/interfaces';
2323
import moment from 'moment';
2424
import { DETECTOR_STATE } from '../../../../server/utils/constants';
25-
import { SINGLE_ENTITY_SHINGLE_SIZE } from '../../../utils/constants';
25+
import { DEFAULT_SHINGLE_SIZE } from '../../../utils/constants';
2626

2727
const detectorFaker = new chance('seed');
2828

@@ -115,7 +115,7 @@ export const getRandomDetector = (isCreate: boolean = true): Detector => {
115115
disabledTime: moment(1586823218000).subtract(1, 'days').valueOf(),
116116
curState: DETECTOR_STATE.INIT,
117117
stateError: '',
118-
shingleSize: SINGLE_ENTITY_SHINGLE_SIZE,
118+
shingleSize: DEFAULT_SHINGLE_SIZE,
119119
};
120120
};
121121

public/utils/constants.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,7 @@ export const MAX_CATEGORY_FIELD_NUM = 2;
8484
export const NAME_REGEX = RegExp('^[a-zA-Z0-9._-]+$');
8585

8686
//https://github.com/opensearch-project/anomaly-detection/blob/main/src/main/java/com/amazon/opendistroforelasticsearch/ad/settings/AnomalyDetectorSettings.java
87-
export const SINGLE_ENTITY_SHINGLE_SIZE = 8;
88-
89-
export const MULTI_ENTITY_SHINGLE_SIZE = 4;
87+
export const DEFAULT_SHINGLE_SIZE = 8;
9088

9189
export const FEATURE_DATA_POINTS_WINDOW = 3;
9290

0 commit comments

Comments
 (0)