[ML] Influencers come after analysis fields (elastic/x-pack-elasticsearch#646)
Original commit: elastic/x-pack-elasticsearch@f37835b140
This commit is contained in:
parent
8ecdf3b288
commit
8a3706f395
|
@ -23,11 +23,10 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anomaly Record POJO.
|
* Anomaly Record POJO.
|
||||||
|
@ -296,7 +295,7 @@ public class AnomalyRecord extends ToXContentToBytes implements Writeable {
|
||||||
builder.field(INFLUENCERS.getPreferredName(), influences);
|
builder.field(INFLUENCERS.getPreferredName(), influences);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Set<String>> inputFields = inputFieldMap();
|
Map<String, LinkedHashSet<String>> inputFields = inputFieldMap();
|
||||||
for (String fieldName : inputFields.keySet()) {
|
for (String fieldName : inputFields.keySet()) {
|
||||||
builder.field(fieldName, inputFields.get(fieldName));
|
builder.field(fieldName, inputFields.get(fieldName));
|
||||||
}
|
}
|
||||||
|
@ -305,8 +304,9 @@ public class AnomalyRecord extends ToXContentToBytes implements Writeable {
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Set<String>> inputFieldMap() {
|
private Map<String, LinkedHashSet<String>> inputFieldMap() {
|
||||||
Map<String, Set<String>> result = new HashMap<>();
|
// LinkedHashSet preserves insertion order when iterating entries
|
||||||
|
Map<String, LinkedHashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
addInputFieldsToMap(result, byFieldName, byFieldValue);
|
addInputFieldsToMap(result, byFieldName, byFieldValue);
|
||||||
addInputFieldsToMap(result, overFieldName, overFieldValue);
|
addInputFieldsToMap(result, overFieldName, overFieldValue);
|
||||||
|
@ -323,10 +323,10 @@ public class AnomalyRecord extends ToXContentToBytes implements Writeable {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addInputFieldsToMap(Map<String, Set<String>> inputFields, String fieldName, String fieldValue) {
|
private void addInputFieldsToMap(Map<String, LinkedHashSet<String>> inputFields, String fieldName, String fieldValue) {
|
||||||
if (!Strings.isNullOrEmpty(fieldName) && fieldValue != null) {
|
if (!Strings.isNullOrEmpty(fieldName) && fieldValue != null) {
|
||||||
if (ReservedFieldNames.isValidFieldName(fieldName)) {
|
if (ReservedFieldNames.isValidFieldName(fieldName)) {
|
||||||
inputFields.computeIfAbsent(fieldName, k -> new HashSet<String>()).add(fieldValue);
|
inputFields.computeIfAbsent(fieldName, k -> new LinkedHashSet<>()).add(fieldValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,6 +115,33 @@ public class AnomalyRecordTests extends AbstractSerializingTestCase<AnomalyRecor
|
||||||
assertEquals(influence2.getInfluencerFieldValues(), serialisedInfFieldValues2);
|
assertEquals(influence2.getInfluencerFieldValues(), serialisedInfFieldValues2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testToXContentOrdersDuplicateInputFields() throws IOException {
|
||||||
|
AnomalyRecord record = createTestInstance();
|
||||||
|
record.setByFieldName("car-make");
|
||||||
|
record.setByFieldValue("ford");
|
||||||
|
record.setOverFieldName("number-of-wheels");
|
||||||
|
record.setOverFieldValue("4");
|
||||||
|
record.setPartitionFieldName("spoiler");
|
||||||
|
record.setPartitionFieldValue("yes");
|
||||||
|
|
||||||
|
Influence influence1 = new Influence("car-make", Collections.singletonList("VW"));
|
||||||
|
Influence influence2 = new Influence("number-of-wheels", Collections.singletonList("18"));
|
||||||
|
Influence influence3 = new Influence("spoiler", Collections.singletonList("no"));
|
||||||
|
record.setInfluencers(Arrays.asList(influence1, influence2, influence3));
|
||||||
|
|
||||||
|
// influencer fields with the same name as a by/over/partitiion field
|
||||||
|
// come second in the list
|
||||||
|
XContentBuilder builder = toXContent(record, XContentType.JSON);
|
||||||
|
XContentParser parser = createParser(builder);
|
||||||
|
Map<String, Object> map = parser.map();
|
||||||
|
List<String> serialisedCarMakeFieldValues = (List<String>) map.get("car-make");
|
||||||
|
assertEquals(Arrays.asList("ford", "VW"), serialisedCarMakeFieldValues);
|
||||||
|
List<String> serialisedNumberOfWheelsFieldValues = (List<String>) map.get("number-of-wheels");
|
||||||
|
assertEquals(Arrays.asList("4", "18"), serialisedNumberOfWheelsFieldValues);
|
||||||
|
List<String> serialisedSpoilerFieldValues = (List<String>) map.get("spoiler");
|
||||||
|
assertEquals(Arrays.asList("yes", "no"), serialisedSpoilerFieldValues);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void testToXContentDoesNotIncludesReservedWordInputFields() throws IOException {
|
public void testToXContentDoesNotIncludesReservedWordInputFields() throws IOException {
|
||||||
AnomalyRecord record = createTestInstance();
|
AnomalyRecord record = createTestInstance();
|
||||||
|
|
Loading…
Reference in New Issue