[ML] Fix filter influencers by score
Add more test coverage Original commit: elastic/x-pack-elasticsearch@45b06d2a5b
This commit is contained in:
parent
5dc8c71e65
commit
2c6a4d8627
|
@ -66,7 +66,7 @@ extends Action<GetInfluencersAction.Request, GetInfluencersAction.Response, GetI
|
|||
public static final ParseField START = new ParseField("start");
|
||||
public static final ParseField END = new ParseField("end");
|
||||
public static final ParseField EXCLUDE_INTERIM = new ParseField("exclude_interim");
|
||||
public static final ParseField ANOMALY_SCORE = new ParseField("anomaly_score");
|
||||
public static final ParseField INFLUENCER_SCORE = new ParseField("influencer_score");
|
||||
public static final ParseField SORT_FIELD = new ParseField("sort");
|
||||
public static final ParseField DESCENDING_SORT = new ParseField("desc");
|
||||
|
||||
|
@ -78,7 +78,7 @@ extends Action<GetInfluencersAction.Request, GetInfluencersAction.Response, GetI
|
|||
PARSER.declareStringOrNull(Request::setEnd, END);
|
||||
PARSER.declareBoolean(Request::setExcludeInterim, EXCLUDE_INTERIM);
|
||||
PARSER.declareObject(Request::setPageParams, PageParams.PARSER, PageParams.PAGE);
|
||||
PARSER.declareDouble(Request::setAnomalyScore, ANOMALY_SCORE);
|
||||
PARSER.declareDouble(Request::setInfluencerScore, INFLUENCER_SCORE);
|
||||
PARSER.declareString(Request::setSort, SORT_FIELD);
|
||||
PARSER.declareBoolean(Request::setDescending, DESCENDING_SORT);
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ extends Action<GetInfluencersAction.Request, GetInfluencersAction.Response, GetI
|
|||
private String end;
|
||||
private boolean excludeInterim = false;
|
||||
private PageParams pageParams = new PageParams();
|
||||
private double anomalyScoreFilter = 0.0;
|
||||
private double influencerScore = 0.0;
|
||||
private String sort = Influencer.INFLUENCER_SCORE.getPreferredName();
|
||||
private boolean descending = false;
|
||||
|
||||
|
@ -151,12 +151,12 @@ extends Action<GetInfluencersAction.Request, GetInfluencersAction.Response, GetI
|
|||
return pageParams;
|
||||
}
|
||||
|
||||
public double getAnomalyScoreFilter() {
|
||||
return anomalyScoreFilter;
|
||||
public double getInfluencerScore() {
|
||||
return influencerScore;
|
||||
}
|
||||
|
||||
public void setAnomalyScore(double anomalyScoreFilter) {
|
||||
this.anomalyScoreFilter = anomalyScoreFilter;
|
||||
public void setInfluencerScore(double anomalyScoreFilter) {
|
||||
this.influencerScore = anomalyScoreFilter;
|
||||
}
|
||||
|
||||
public String getSort() {
|
||||
|
@ -182,7 +182,7 @@ extends Action<GetInfluencersAction.Request, GetInfluencersAction.Response, GetI
|
|||
end = in.readOptionalString();
|
||||
sort = in.readOptionalString();
|
||||
descending = in.readBoolean();
|
||||
anomalyScoreFilter = in.readDouble();
|
||||
influencerScore = in.readDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -195,7 +195,7 @@ extends Action<GetInfluencersAction.Request, GetInfluencersAction.Response, GetI
|
|||
out.writeOptionalString(end);
|
||||
out.writeOptionalString(sort);
|
||||
out.writeBoolean(descending);
|
||||
out.writeDouble(anomalyScoreFilter);
|
||||
out.writeDouble(influencerScore);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -208,14 +208,14 @@ extends Action<GetInfluencersAction.Request, GetInfluencersAction.Response, GetI
|
|||
builder.field(END.getPreferredName(), end);
|
||||
builder.field(SORT_FIELD.getPreferredName(), sort);
|
||||
builder.field(DESCENDING_SORT.getPreferredName(), descending);
|
||||
builder.field(ANOMALY_SCORE.getPreferredName(), anomalyScoreFilter);
|
||||
builder.field(INFLUENCER_SCORE.getPreferredName(), influencerScore);
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(jobId, excludeInterim, pageParams, start, end, sort, descending, anomalyScoreFilter);
|
||||
return Objects.hash(jobId, excludeInterim, pageParams, start, end, sort, descending, influencerScore);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -231,7 +231,7 @@ extends Action<GetInfluencersAction.Request, GetInfluencersAction.Response, GetI
|
|||
&& Objects.equals(end, other.end)
|
||||
&& Objects.equals(excludeInterim, other.excludeInterim)
|
||||
&& Objects.equals(pageParams, other.pageParams)
|
||||
&& Objects.equals(anomalyScoreFilter, other.anomalyScoreFilter)
|
||||
&& Objects.equals(influencerScore, other.influencerScore)
|
||||
&& Objects.equals(descending, other.descending)
|
||||
&& Objects.equals(sort, other.sort);
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ extends Action<GetInfluencersAction.Request, GetInfluencersAction.Response, GetI
|
|||
|
||||
InfluencersQueryBuilder.InfluencersQuery query = new InfluencersQueryBuilder().includeInterim(request.excludeInterim == false)
|
||||
.start(request.start).end(request.end).from(request.pageParams.getFrom()).size(request.pageParams.getSize())
|
||||
.anomalyScoreThreshold(request.anomalyScoreFilter).sortField(request.sort).sortDescending(request.descending).build();
|
||||
.influencerScoreThreshold(request.influencerScore).sortField(request.sort).sortDescending(request.descending).build();
|
||||
jobProvider.influencers(request.jobId, query, page -> listener.onResponse(new Response(page)), listener::onFailure, client);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ public final class InfluencersQueryBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public InfluencersQueryBuilder anomalyScoreThreshold(Double anomalyScoreFilter) {
|
||||
influencersQuery.anomalyScoreFilter = anomalyScoreFilter;
|
||||
public InfluencersQueryBuilder influencerScoreThreshold(Double influencerScoreFilter) {
|
||||
influencersQuery.influencerScoreFilter = influencerScoreFilter;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ public final class InfluencersQueryBuilder {
|
|||
private int from = 0;
|
||||
private int size = DEFAULT_SIZE;
|
||||
private boolean includeInterim = false;
|
||||
private double anomalyScoreFilter = 0.0d;
|
||||
private double influencerScoreFilter = 0.0d;
|
||||
private String start;
|
||||
private String end;
|
||||
private String sortField = Influencer.INFLUENCER_SCORE.getPreferredName();
|
||||
|
@ -109,8 +109,8 @@ public final class InfluencersQueryBuilder {
|
|||
return includeInterim;
|
||||
}
|
||||
|
||||
public double getAnomalyScoreFilter() {
|
||||
return anomalyScoreFilter;
|
||||
public double getInfluencerScoreFilter() {
|
||||
return influencerScoreFilter;
|
||||
}
|
||||
|
||||
public String getStart() {
|
||||
|
@ -131,7 +131,7 @@ public final class InfluencersQueryBuilder {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(from, size, includeInterim, anomalyScoreFilter, start, end, sortField, sortDescending);
|
||||
return Objects.hash(from, size, includeInterim, influencerScoreFilter, start, end, sortField, sortDescending);
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,7 +153,7 @@ public final class InfluencersQueryBuilder {
|
|||
Objects.equals(includeInterim, other.includeInterim) &&
|
||||
Objects.equals(start, other.start) &&
|
||||
Objects.equals(end, other.end) &&
|
||||
Objects.equals(anomalyScoreFilter, other.anomalyScoreFilter) &&
|
||||
Objects.equals(influencerScoreFilter, other.influencerScoreFilter) &&
|
||||
Objects.equals(sortField, other.sortField) &&
|
||||
this.sortDescending == other.sortDescending;
|
||||
}
|
||||
|
|
|
@ -710,7 +710,7 @@ public class JobProvider {
|
|||
Consumer<Exception> errorHandler, Client client) {
|
||||
QueryBuilder fb = new ResultsFilterBuilder()
|
||||
.timeRange(Result.TIMESTAMP.getPreferredName(), query.getStart(), query.getEnd())
|
||||
.score(Bucket.ANOMALY_SCORE.getPreferredName(), query.getAnomalyScoreFilter())
|
||||
.score(Influencer.INFLUENCER_SCORE.getPreferredName(), query.getInfluencerScoreFilter())
|
||||
.interim(Bucket.IS_INTERIM.getPreferredName(), query.isIncludeInterim())
|
||||
.build();
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ public class RestGetInfluencersAction extends BaseRestHandler {
|
|||
request.setExcludeInterim(restRequest.paramAsBoolean(GetInfluencersAction.Request.EXCLUDE_INTERIM.getPreferredName(), false));
|
||||
request.setPageParams(new PageParams(restRequest.paramAsInt(PageParams.FROM.getPreferredName(), PageParams.DEFAULT_FROM),
|
||||
restRequest.paramAsInt(PageParams.SIZE.getPreferredName(), PageParams.DEFAULT_SIZE)));
|
||||
request.setAnomalyScore(
|
||||
Double.parseDouble(restRequest.param(GetInfluencersAction.Request.ANOMALY_SCORE.getPreferredName(), "0.0")));
|
||||
request.setInfluencerScore(
|
||||
Double.parseDouble(restRequest.param(GetInfluencersAction.Request.INFLUENCER_SCORE.getPreferredName(), "0.0")));
|
||||
request.setSort(restRequest.param(GetInfluencersAction.Request.SORT_FIELD.getPreferredName(),
|
||||
Influencer.INFLUENCER_SCORE.getPreferredName()));
|
||||
request.setDescending(restRequest.paramAsBoolean(GetInfluencersAction.Request.DESCENDING_SORT.getPreferredName(), true));
|
||||
|
|
|
@ -29,7 +29,7 @@ public class GetInfluencersActionRequestTests extends AbstractStreamableXContent
|
|||
request.setEnd(end);
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
request.setAnomalyScore(randomDouble());
|
||||
request.setInfluencerScore(randomDouble());
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
request.setExcludeInterim(randomBoolean());
|
||||
|
|
|
@ -16,7 +16,7 @@ public class InfluencersQueryBuilderTests extends ESTestCase {
|
|||
assertEquals(0, query.getFrom());
|
||||
assertEquals(InfluencersQueryBuilder.DEFAULT_SIZE, query.getSize());
|
||||
assertEquals(false, query.isIncludeInterim());
|
||||
assertEquals(0.0, query.getAnomalyScoreFilter(), 0.0001);
|
||||
assertEquals(0.0, query.getInfluencerScoreFilter(), 0.0001);
|
||||
assertNull(query.getStart());
|
||||
assertNull(query.getEnd());
|
||||
assertEquals(Influencer.INFLUENCER_SCORE.getPreferredName(), query.getSortField());
|
||||
|
@ -28,7 +28,7 @@ public class InfluencersQueryBuilderTests extends ESTestCase {
|
|||
.from(20)
|
||||
.size(40)
|
||||
.includeInterim(true)
|
||||
.anomalyScoreThreshold(50.0d)
|
||||
.influencerScoreThreshold(50.0d)
|
||||
.start("1000")
|
||||
.end("2000")
|
||||
.sortField("anomaly_score")
|
||||
|
@ -38,7 +38,7 @@ public class InfluencersQueryBuilderTests extends ESTestCase {
|
|||
assertEquals(20, query.getFrom());
|
||||
assertEquals(40, query.getSize());
|
||||
assertEquals(true, query.isIncludeInterim());
|
||||
assertEquals(50.0d, query.getAnomalyScoreFilter(), 0.00001);
|
||||
assertEquals(50.0d, query.getInfluencerScoreFilter(), 0.00001);
|
||||
assertEquals("1000", query.getStart());
|
||||
assertEquals("2000", query.getEnd());
|
||||
assertEquals("anomaly_score", query.getSortField());
|
||||
|
@ -50,7 +50,7 @@ public class InfluencersQueryBuilderTests extends ESTestCase {
|
|||
.from(20)
|
||||
.size(40)
|
||||
.includeInterim(true)
|
||||
.anomalyScoreThreshold(50.0d)
|
||||
.influencerScoreThreshold(50.0d)
|
||||
.start("1000")
|
||||
.end("2000");
|
||||
|
||||
|
@ -58,7 +58,7 @@ public class InfluencersQueryBuilderTests extends ESTestCase {
|
|||
.from(20)
|
||||
.size(40)
|
||||
.includeInterim(true)
|
||||
.anomalyScoreThreshold(50.0d)
|
||||
.influencerScoreThreshold(50.0d)
|
||||
.start("1000")
|
||||
.end("2000");
|
||||
|
||||
|
@ -70,7 +70,7 @@ public class InfluencersQueryBuilderTests extends ESTestCase {
|
|||
query2.from(20)
|
||||
.size(40)
|
||||
.includeInterim(true)
|
||||
.anomalyScoreThreshold(50.0d)
|
||||
.influencerScoreThreshold(50.0d)
|
||||
.start("1000")
|
||||
.end("2000");
|
||||
assertEquals(query.build(), query2.build());
|
||||
|
@ -79,7 +79,7 @@ public class InfluencersQueryBuilderTests extends ESTestCase {
|
|||
query2.from(20)
|
||||
.size(40)
|
||||
.includeInterim(true)
|
||||
.anomalyScoreThreshold(50.1d)
|
||||
.influencerScoreThreshold(50.1d)
|
||||
.start("1000")
|
||||
.end("2000");
|
||||
assertFalse(query.build().equals(query2.build()));
|
||||
|
|
|
@ -738,7 +738,7 @@ public class JobProviderTests extends ESTestCase {
|
|||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
QueryPage<Influencer>[] holder = new QueryPage[1];
|
||||
InfluencersQuery query = new InfluencersQueryBuilder().from(from).size(size).start("0").end("0").sortField("sort")
|
||||
.sortDescending(true).anomalyScoreThreshold(0.0).includeInterim(true).build();
|
||||
.sortDescending(true).influencerScoreThreshold(0.0).includeInterim(true).build();
|
||||
provider.influencers(jobId, query, page -> holder[0] = page, RuntimeException::new, client);
|
||||
QueryPage<Influencer> page = holder[0];
|
||||
assertEquals(2L, page.count());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
setup:
|
||||
- do:
|
||||
xpack.ml.put_job:
|
||||
job_id: farequote
|
||||
job_id: get-influencers-test
|
||||
body: >
|
||||
{
|
||||
"analysis_config" : {
|
||||
|
@ -15,16 +15,16 @@ setup:
|
|||
|
||||
- do:
|
||||
index:
|
||||
index: .ml-anomalies-farequote
|
||||
index: .ml-anomalies-get-influencers-test
|
||||
type: result
|
||||
id: farequote_1464739200000_1_1
|
||||
id: get-influencers-test_1464739200000_1_1
|
||||
body:
|
||||
{
|
||||
"job_id": "farequote",
|
||||
"job_id": "get-influencers-test",
|
||||
"timestamp": "2016-06-01T00:00:00Z",
|
||||
"influencer_field_name": "foo",
|
||||
"influencer_field_value": "bar",
|
||||
"influencer_score": 80.0,
|
||||
"influencer_score": 50.0,
|
||||
"result_type" : "influencer",
|
||||
"bucket_span" : 1,
|
||||
"sequence_num" : 1
|
||||
|
@ -32,60 +32,84 @@ setup:
|
|||
|
||||
- do:
|
||||
index:
|
||||
index: .ml-anomalies-farequote
|
||||
index: .ml-anomalies-get-influencers-test
|
||||
type: result
|
||||
id: farequote_1464825600000_1_2
|
||||
id: get-influencers-test_1464825600000_1_2
|
||||
body:
|
||||
{
|
||||
"job_id": "farequote",
|
||||
"job_id": "get-influencers-test",
|
||||
"timestamp": "2016-06-02T00:00:00Z",
|
||||
"influencer_field_name": "foo",
|
||||
"influencer_field_value": "zoo",
|
||||
"influencer_score": 50.0,
|
||||
"influencer_score": 80.0,
|
||||
"result_type" : "influencer",
|
||||
"bucket_span" : 1,
|
||||
"sequence_num" : 2,
|
||||
"is_interim": true
|
||||
}
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: .ml-anomalies-get-influencers-test
|
||||
type: result
|
||||
id: get-influencers-test_1464912000000_1_3
|
||||
body:
|
||||
{
|
||||
"job_id": "get-influencers-test",
|
||||
"timestamp": "2016-06-03T00:00:00Z",
|
||||
"influencer_field_name": "foo",
|
||||
"influencer_field_value": "zoo",
|
||||
"influencer_score": 60.0,
|
||||
"result_type" : "influencer",
|
||||
"bucket_span" : 1,
|
||||
"sequence_num" : 2
|
||||
}
|
||||
|
||||
- do:
|
||||
indices.refresh:
|
||||
index: .ml-anomalies-farequote
|
||||
index: .ml-anomalies-get-influencers-test
|
||||
|
||||
---
|
||||
"Test result influencers api":
|
||||
- do:
|
||||
xpack.ml.get_influencers:
|
||||
job_id: "farequote"
|
||||
job_id: "get-influencers-test"
|
||||
|
||||
- match: { count: 2 }
|
||||
- match: { influencers.0.timestamp: 1464739200000 }
|
||||
- match: { influencers.1.timestamp: 1464825600000 }
|
||||
- match: { count: 3 }
|
||||
- match: { influencers.0.influencer_score: 80 }
|
||||
- match: { influencers.0.timestamp: 1464825600000 }
|
||||
- match: { influencers.1.influencer_score: 60 }
|
||||
- match: { influencers.1.timestamp: 1464912000000 }
|
||||
- match: { influencers.2.influencer_score: 50 }
|
||||
- match: { influencers.2.timestamp: 1464739200000 }
|
||||
|
||||
---
|
||||
"Test get influencers given exclude_interim false":
|
||||
- do:
|
||||
xpack.ml.get_influencers:
|
||||
job_id: "farequote"
|
||||
job_id: "get-influencers-test"
|
||||
exclude_interim: false
|
||||
|
||||
- match: { count: 2 }
|
||||
- match: { count: 3 }
|
||||
|
||||
---
|
||||
"Test get influencers given exclude_interim true":
|
||||
- do:
|
||||
xpack.ml.get_influencers:
|
||||
job_id: "farequote"
|
||||
job_id: "get-influencers-test"
|
||||
exclude_interim: true
|
||||
|
||||
- match: { count: 1 }
|
||||
- match: { influencers.0.timestamp: 1464739200000 }
|
||||
- match: { count: 2 }
|
||||
- match: { influencers.0.timestamp: 1464912000000 }
|
||||
- match: { influencers.0.is_interim: false }
|
||||
- match: { influencers.1.timestamp: 1464739200000 }
|
||||
- match: { influencers.1.is_interim: false }
|
||||
|
||||
---
|
||||
"Test result influencers api with time range":
|
||||
- do:
|
||||
xpack.ml.get_influencers:
|
||||
job_id: "farequote"
|
||||
job_id: "get-influencers-test"
|
||||
start: "2016-06-01T00:00:00Z"
|
||||
end: "2016-06-01T01:00:00Z"
|
||||
|
||||
|
@ -98,3 +122,35 @@ setup:
|
|||
catch: missing
|
||||
xpack.ml.get_influencers:
|
||||
job_id: "non-existent-job"
|
||||
|
||||
---
|
||||
"Test get influencers api with influencer score filter":
|
||||
- do:
|
||||
xpack.ml.get_influencers:
|
||||
job_id: "get-influencers-test"
|
||||
influencer_score: 70
|
||||
|
||||
- match: { count: 1 }
|
||||
- match: { influencers.0.timestamp: 1464825600000 }
|
||||
|
||||
---
|
||||
"Test get influencers api sort":
|
||||
- do:
|
||||
xpack.ml.get_influencers:
|
||||
job_id: "get-influencers-test"
|
||||
desc: false
|
||||
|
||||
- match: { count: 3 }
|
||||
- match: { influencers.0.influencer_score: 50 }
|
||||
- match: { influencers.1.influencer_score: 60 }
|
||||
- match: { influencers.2.influencer_score: 80}
|
||||
|
||||
- do:
|
||||
xpack.ml.get_influencers:
|
||||
job_id: "get-influencers-test"
|
||||
sort: timestamp
|
||||
|
||||
- match: { count: 3 }
|
||||
- match: { influencers.0.timestamp: 1464912000000 }
|
||||
- match: { influencers.1.timestamp: 1464825600000 }
|
||||
- match: { influencers.2.timestamp: 1464739200000 }
|
||||
|
|
Loading…
Reference in New Issue