-
Notifications
You must be signed in to change notification settings - Fork 24.3k
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] Add new geo_results.(actual_point|typical_point) fields for lat_long
results
#47050
Changes from 7 commits
b939b82
b05ba94
89a23b6
5aa0589
1598c1f
3db79b8
5fbba22
a71940b
62b04c0
6752b61
f4191b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
import org.elasticsearch.common.xcontent.ObjectParser; | ||
import org.elasticsearch.common.xcontent.ToXContentObject; | ||
import org.elasticsearch.common.xcontent.XContentBuilder; | ||
import org.elasticsearch.xpack.core.ml.job.config.DetectorFunction; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
|
@@ -39,6 +40,7 @@ public class AnomalyCause implements ToXContentObject, Writeable { | |
public static final ParseField TYPICAL = new ParseField("typical"); | ||
public static final ParseField ACTUAL = new ParseField("actual"); | ||
public static final ParseField INFLUENCERS = new ParseField("influencers"); | ||
public static final ParseField GEO_RESULTS = new ParseField("geo_results"); | ||
|
||
/** | ||
* Metric Results | ||
|
@@ -189,10 +191,26 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws | |
if (influencers != null) { | ||
builder.field(INFLUENCERS.getPreferredName(), influencers); | ||
} | ||
if (DetectorFunction.LAT_LONG.getFullName().equals(function)) { | ||
builder.startObject(GEO_RESULTS.getPreferredName()); | ||
writeDoublesAsGeoPoint(builder, ACTUAL.getPreferredName(), actual); | ||
writeDoublesAsGeoPoint(builder, TYPICAL.getPreferredName(), typical); | ||
builder.endObject(); | ||
} | ||
builder.endObject(); | ||
return builder; | ||
} | ||
|
||
private void writeDoublesAsGeoPoint(XContentBuilder builder, String fieldName, List<Double> doubles) throws IOException { | ||
if (doubles != null) { | ||
//TODO should we fail if `doubles` is not an array of length 2? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think an internal assertion as you've got it now is best. Throwing an exception here would mean it was impossible to get anything from the results endpoint. However, see my main comment because that would render this a moot point as the whole method could be deleted. |
||
assert doubles.size() == 2 : "for lat_lon function [" + fieldName + "] result has invalid format " + doubles; | ||
if (doubles.size() == 2) { | ||
builder.field(fieldName, doubles.get(0) + "," + doubles.get(1)); | ||
} | ||
} | ||
} | ||
|
||
|
||
public double getProbability() { | ||
return probability; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
import org.elasticsearch.common.xcontent.ToXContentObject; | ||
import org.elasticsearch.common.xcontent.XContentBuilder; | ||
import org.elasticsearch.xpack.core.ml.job.config.Detector; | ||
import org.elasticsearch.xpack.core.ml.job.config.DetectorFunction; | ||
import org.elasticsearch.xpack.core.ml.job.config.Job; | ||
import org.elasticsearch.xpack.core.ml.utils.ExceptionsHelper; | ||
import org.elasticsearch.xpack.core.common.time.TimeUtils; | ||
|
@@ -55,6 +56,7 @@ public class AnomalyRecord implements ToXContentObject, Writeable { | |
public static final ParseField ACTUAL = new ParseField("actual"); | ||
public static final ParseField INFLUENCERS = new ParseField("influencers"); | ||
public static final ParseField BUCKET_SPAN = new ParseField("bucket_span"); | ||
public static final ParseField GEO_RESULTS = new ParseField("geo_results"); | ||
|
||
// Used for QueryPage | ||
public static final ParseField RESULTS_FIELD = new ParseField("records"); | ||
|
@@ -290,11 +292,21 @@ XContentBuilder innerToXContent(XContentBuilder builder, Params params) throws I | |
builder.field(OVER_FIELD_VALUE.getPreferredName(), overFieldValue); | ||
} | ||
if (causes != null) { | ||
builder.field(CAUSES.getPreferredName(), causes); | ||
builder.startArray(CAUSES.getPreferredName()); | ||
for (AnomalyCause cause : causes) { | ||
builder.value(cause, params); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line could be changed to |
||
} | ||
builder.endArray(); | ||
} | ||
if (influences != null) { | ||
builder.field(INFLUENCERS.getPreferredName(), influences); | ||
} | ||
if (DetectorFunction.LAT_LONG.getFullName().equals(function)) { | ||
builder.startObject(GEO_RESULTS.getPreferredName()); | ||
writeDoublesAsGeoPoint(builder, ACTUAL.getPreferredName(), actual); | ||
writeDoublesAsGeoPoint(builder, TYPICAL.getPreferredName(), typical); | ||
builder.endObject(); | ||
} | ||
|
||
Map<String, LinkedHashSet<String>> inputFields = inputFieldMap(); | ||
for (String fieldName : inputFields.keySet()) { | ||
|
@@ -303,6 +315,17 @@ XContentBuilder innerToXContent(XContentBuilder builder, Params params) throws I | |
return builder; | ||
} | ||
|
||
|
||
private void writeDoublesAsGeoPoint(XContentBuilder builder, String fieldName, List<Double> doubles) throws IOException { | ||
if (doubles != null) { | ||
//TODO should we fail if `doubles` is not an array of length 2? | ||
assert doubles.size() == 2 : "for lat_lon function [" + fieldName + "] result has invalid format " + doubles; | ||
if (doubles.size() == 2) { | ||
builder.field(fieldName, doubles.get(0) + "," + doubles.get(1)); | ||
} | ||
} | ||
} | ||
|
||
private Map<String, LinkedHashSet<String>> inputFieldMap() { | ||
// LinkedHashSet preserves insertion order when iterating entries | ||
Map<String, LinkedHashSet<String>> result = new HashMap<>(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really see why making this public would be a problem given what it does and the other public methods nearby. However, you should probably run this by somebody in the ES core infra team before merging.
There is a simple way to avoid making this public - see my next comment.