Skip to content

Commit 6c1700c

Browse files
[7.x][ML] Outlier detection mapping for nested feature influence (#62068) (#62150)
Adds mappings for outlier detection results. Backport of #62068
1 parent 146b2e6 commit 6c1700c

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/dataframe/analyses/OutlierDetection.java

+22-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
import org.elasticsearch.common.xcontent.ObjectParser;
1414
import org.elasticsearch.common.xcontent.XContentBuilder;
1515
import org.elasticsearch.common.xcontent.XContentParser;
16+
import org.elasticsearch.index.mapper.KeywordFieldMapper;
17+
import org.elasticsearch.index.mapper.NumberFieldMapper;
18+
import org.elasticsearch.index.mapper.ObjectMapper;
1619
import org.elasticsearch.xpack.core.ml.inference.trainedmodel.InferenceConfig;
1720
import org.elasticsearch.xpack.core.ml.utils.ExceptionsHelper;
1821

@@ -56,6 +59,20 @@ public static OutlierDetection fromXContent(XContentParser parser, boolean ignor
5659

5760
private static final List<String> PROGRESS_PHASES = Collections.singletonList("computing_outliers");
5861

62+
static final Map<String, Object> FEATURE_INFLUENCE_MAPPING;
63+
static {
64+
Map<String, Object> properties = new HashMap<>();
65+
properties.put("feature_name", Collections.singletonMap("type", KeywordFieldMapper.CONTENT_TYPE));
66+
properties.put("influence", Collections.singletonMap("type", NumberFieldMapper.NumberType.DOUBLE.typeName()));
67+
68+
Map<String, Object> mapping = new HashMap<>();
69+
mapping.put("dynamic", false);
70+
mapping.put("type", ObjectMapper.NESTED_CONTENT_TYPE);
71+
mapping.put("properties", properties);
72+
73+
FEATURE_INFLUENCE_MAPPING = Collections.unmodifiableMap(mapping);
74+
}
75+
5976
/**
6077
* The number of neighbors. Leave unspecified for dynamic detection.
6178
*/
@@ -229,7 +246,11 @@ public List<FieldCardinalityConstraint> getFieldCardinalityConstraints() {
229246

230247
@Override
231248
public Map<String, Object> getExplicitlyMappedFields(Map<String, Object> mappingsProperties, String resultsFieldName) {
232-
return Collections.emptyMap();
249+
Map<String, Object> additionalProperties = new HashMap<>();
250+
additionalProperties.put(resultsFieldName + ".outlier_score",
251+
Collections.singletonMap("type", NumberFieldMapper.NumberType.DOUBLE.typeName()));
252+
additionalProperties.put(resultsFieldName + ".feature_influence", FEATURE_INFLUENCE_MAPPING);
253+
return additionalProperties;
233254
}
234255

235256
@Override

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/dataframe/analyses/OutlierDetectionTests.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@
88
import org.elasticsearch.Version;
99
import org.elasticsearch.common.io.stream.Writeable;
1010
import org.elasticsearch.common.xcontent.XContentParser;
11+
import org.elasticsearch.index.mapper.NumberFieldMapper;
1112
import org.elasticsearch.xpack.core.ml.AbstractBWCSerializationTestCase;
1213

1314
import java.io.IOException;
15+
import java.util.Collections;
1416
import java.util.Map;
1517

16-
import static org.hamcrest.Matchers.anEmptyMap;
1718
import static org.hamcrest.Matchers.closeTo;
1819
import static org.hamcrest.Matchers.empty;
1920
import static org.hamcrest.Matchers.equalTo;
21+
import static org.hamcrest.Matchers.hasKey;
2022
import static org.hamcrest.Matchers.is;
2123
import static org.hamcrest.Matchers.nullValue;
2224

@@ -106,7 +108,13 @@ public void testFieldCardinalityLimitsIsEmpty() {
106108
}
107109

108110
public void testGetExplicitlyMappedFields() {
109-
assertThat(createTestInstance().getExplicitlyMappedFields(null, null), is(anEmptyMap()));
111+
Map<String, Object> mappedFields = createTestInstance().getExplicitlyMappedFields(null, "test");
112+
assertThat(mappedFields.size(), equalTo(2));
113+
assertThat(mappedFields, hasKey("test.outlier_score"));
114+
assertThat(mappedFields.get("test.outlier_score"),
115+
equalTo(Collections.singletonMap("type", NumberFieldMapper.NumberType.DOUBLE.typeName())));
116+
assertThat(mappedFields, hasKey("test.feature_influence"));
117+
assertThat(mappedFields.get("test.feature_influence"), equalTo(OutlierDetection.FEATURE_INFLUENCE_MAPPING));
110118
}
111119

112120
public void testGetStateDocId() {

0 commit comments

Comments
 (0)