HLRC: Add ML get categories API (#33465)
HLRC: Adding the ML 'get categories' API
This commit is contained in:
parent
a3e1f1e46f
commit
2f3b542d57
|
@ -32,6 +32,7 @@ import org.elasticsearch.client.ml.DeleteJobRequest;
|
|||
import org.elasticsearch.client.ml.FlushJobRequest;
|
||||
import org.elasticsearch.client.ml.ForecastJobRequest;
|
||||
import org.elasticsearch.client.ml.GetBucketsRequest;
|
||||
import org.elasticsearch.client.ml.GetCategoriesRequest;
|
||||
import org.elasticsearch.client.ml.GetInfluencersRequest;
|
||||
import org.elasticsearch.client.ml.GetJobRequest;
|
||||
import org.elasticsearch.client.ml.GetJobStatsRequest;
|
||||
|
@ -194,6 +195,20 @@ final class MLRequestConverters {
|
|||
return request;
|
||||
}
|
||||
|
||||
static Request getCategories(GetCategoriesRequest getCategoriesRequest) throws IOException {
|
||||
String endpoint = new EndpointBuilder()
|
||||
.addPathPartAsIs("_xpack")
|
||||
.addPathPartAsIs("ml")
|
||||
.addPathPartAsIs("anomaly_detectors")
|
||||
.addPathPart(getCategoriesRequest.getJobId())
|
||||
.addPathPartAsIs("results")
|
||||
.addPathPartAsIs("categories")
|
||||
.build();
|
||||
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
|
||||
request.setEntity(createEntity(getCategoriesRequest, REQUEST_BODY_CONTENT_TYPE));
|
||||
return request;
|
||||
}
|
||||
|
||||
static Request getOverallBuckets(GetOverallBucketsRequest getOverallBucketsRequest) throws IOException {
|
||||
String endpoint = new EndpointBuilder()
|
||||
.addPathPartAsIs("_xpack")
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.elasticsearch.client.ml.FlushJobRequest;
|
|||
import org.elasticsearch.client.ml.FlushJobResponse;
|
||||
import org.elasticsearch.client.ml.GetBucketsRequest;
|
||||
import org.elasticsearch.client.ml.GetBucketsResponse;
|
||||
import org.elasticsearch.client.ml.GetCategoriesRequest;
|
||||
import org.elasticsearch.client.ml.GetCategoriesResponse;
|
||||
import org.elasticsearch.client.ml.GetInfluencersRequest;
|
||||
import org.elasticsearch.client.ml.GetInfluencersResponse;
|
||||
import org.elasticsearch.client.ml.GetJobRequest;
|
||||
|
@ -474,6 +476,45 @@ public final class MachineLearningClient {
|
|||
Collections.emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the categories for a Machine Learning Job.
|
||||
* <p>
|
||||
* For additional info
|
||||
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-category.html">
|
||||
* ML GET categories documentation</a>
|
||||
*
|
||||
* @param request The request
|
||||
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
|
||||
* @throws IOException when there is a serialization issue sending the request or receiving the response
|
||||
*/
|
||||
public GetCategoriesResponse getCategories(GetCategoriesRequest request, RequestOptions options) throws IOException {
|
||||
return restHighLevelClient.performRequestAndParseEntity(request,
|
||||
MLRequestConverters::getCategories,
|
||||
options,
|
||||
GetCategoriesResponse::fromXContent,
|
||||
Collections.emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the categories for a Machine Learning Job, notifies listener once the requested buckets are retrieved.
|
||||
* <p>
|
||||
* For additional info
|
||||
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-category.html">
|
||||
* ML GET categories documentation</a>
|
||||
*
|
||||
* @param request The request
|
||||
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
|
||||
* @param listener Listener to be notified upon request completion
|
||||
*/
|
||||
public void getCategoriesAsync(GetCategoriesRequest request, RequestOptions options, ActionListener<GetCategoriesResponse> listener) {
|
||||
restHighLevelClient.performRequestAsyncAndParseEntity(request,
|
||||
MLRequestConverters::getCategories,
|
||||
options,
|
||||
GetCategoriesResponse::fromXContent,
|
||||
listener,
|
||||
Collections.emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets overall buckets for a set of Machine Learning Jobs.
|
||||
* <p>
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.elasticsearch.client.ml;
|
||||
|
||||
import org.elasticsearch.action.ActionRequest;
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.client.ml.job.config.Job;
|
||||
import org.elasticsearch.client.ml.job.util.PageParams;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A request to retrieve categories of a given job
|
||||
*/
|
||||
public class GetCategoriesRequest extends ActionRequest implements ToXContentObject {
|
||||
|
||||
|
||||
public static final ParseField CATEGORY_ID = new ParseField("category_id");
|
||||
|
||||
public static final ConstructingObjectParser<GetCategoriesRequest, Void> PARSER = new ConstructingObjectParser<>(
|
||||
"get_categories_request", a -> new GetCategoriesRequest((String) a[0]));
|
||||
|
||||
|
||||
static {
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), Job.ID);
|
||||
PARSER.declareLong(GetCategoriesRequest::setCategoryId, CATEGORY_ID);
|
||||
PARSER.declareObject(GetCategoriesRequest::setPageParams, PageParams.PARSER, PageParams.PAGE);
|
||||
}
|
||||
|
||||
private final String jobId;
|
||||
private Long categoryId;
|
||||
private PageParams pageParams;
|
||||
|
||||
/**
|
||||
* Constructs a request to retrieve category information from a given job
|
||||
* @param jobId id of the job from which to retrieve results
|
||||
*/
|
||||
public GetCategoriesRequest(String jobId) {
|
||||
this.jobId = Objects.requireNonNull(jobId);
|
||||
}
|
||||
|
||||
public String getJobId() {
|
||||
return jobId;
|
||||
}
|
||||
|
||||
public PageParams getPageParams() {
|
||||
return pageParams;
|
||||
}
|
||||
|
||||
public Long getCategoryId() {
|
||||
return categoryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the category id
|
||||
* @param categoryId the category id
|
||||
*/
|
||||
public void setCategoryId(Long categoryId) {
|
||||
this.categoryId = categoryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the paging parameters
|
||||
* @param pageParams the paging parameters
|
||||
*/
|
||||
public void setPageParams(PageParams pageParams) {
|
||||
this.pageParams = pageParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionRequestValidationException validate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field(Job.ID.getPreferredName(), jobId);
|
||||
if (categoryId != null) {
|
||||
builder.field(CATEGORY_ID.getPreferredName(), categoryId);
|
||||
}
|
||||
if (pageParams != null) {
|
||||
builder.field(PageParams.PAGE.getPreferredName(), pageParams);
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
GetCategoriesRequest request = (GetCategoriesRequest) obj;
|
||||
return Objects.equals(jobId, request.jobId)
|
||||
&& Objects.equals(categoryId, request.categoryId)
|
||||
&& Objects.equals(pageParams, request.pageParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(jobId, categoryId, pageParams);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.elasticsearch.client.ml;
|
||||
|
||||
import org.elasticsearch.client.ml.job.results.CategoryDefinition;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A response containing the requested categories
|
||||
*/
|
||||
public class GetCategoriesResponse extends AbstractResultResponse<CategoryDefinition> {
|
||||
|
||||
public static final ParseField CATEGORIES = new ParseField("categories");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static final ConstructingObjectParser<GetCategoriesResponse, Void> PARSER =
|
||||
new ConstructingObjectParser<>("get_categories_response", true,
|
||||
a -> new GetCategoriesResponse((List<CategoryDefinition>) a[0], (long) a[1]));
|
||||
|
||||
static {
|
||||
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), CategoryDefinition.PARSER, CATEGORIES);
|
||||
PARSER.declareLong(ConstructingObjectParser.constructorArg(), COUNT);
|
||||
}
|
||||
|
||||
public static GetCategoriesResponse fromXContent(XContentParser parser) throws IOException {
|
||||
return PARSER.parse(parser, null);
|
||||
}
|
||||
|
||||
GetCategoriesResponse(List<CategoryDefinition> categories, long count) {
|
||||
super(CATEGORIES, categories, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* The retrieved categories
|
||||
* @return the retrieved categories
|
||||
*/
|
||||
public List<CategoryDefinition> categories() {
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(count, results);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
GetCategoriesResponse other = (GetCategoriesResponse) obj;
|
||||
return count == other.count && Objects.equals(results, other.results);
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ import org.elasticsearch.client.ml.DeleteJobRequest;
|
|||
import org.elasticsearch.client.ml.FlushJobRequest;
|
||||
import org.elasticsearch.client.ml.ForecastJobRequest;
|
||||
import org.elasticsearch.client.ml.GetBucketsRequest;
|
||||
import org.elasticsearch.client.ml.GetCategoriesRequest;
|
||||
import org.elasticsearch.client.ml.GetInfluencersRequest;
|
||||
import org.elasticsearch.client.ml.GetJobRequest;
|
||||
import org.elasticsearch.client.ml.GetJobStatsRequest;
|
||||
|
@ -220,6 +221,21 @@ public class MLRequestConvertersTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testGetCategories() throws IOException {
|
||||
String jobId = randomAlphaOfLength(10);
|
||||
GetCategoriesRequest getCategoriesRequest = new GetCategoriesRequest(jobId);
|
||||
getCategoriesRequest.setPageParams(new PageParams(100, 300));
|
||||
|
||||
|
||||
Request request = MLRequestConverters.getCategories(getCategoriesRequest);
|
||||
assertEquals(HttpGet.METHOD_NAME, request.getMethod());
|
||||
assertEquals("/_xpack/ml/anomaly_detectors/" + jobId + "/results/categories", request.getEndpoint());
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, request.getEntity().getContent())) {
|
||||
GetCategoriesRequest parsedRequest = GetCategoriesRequest.PARSER.apply(parser, null);
|
||||
assertThat(parsedRequest, equalTo(getCategoriesRequest));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetOverallBuckets() throws IOException {
|
||||
String jobId = randomAlphaOfLength(10);
|
||||
GetOverallBucketsRequest getOverallBucketsRequest = new GetOverallBucketsRequest(jobId);
|
||||
|
|
|
@ -23,6 +23,8 @@ import org.elasticsearch.action.index.IndexRequest;
|
|||
import org.elasticsearch.action.support.WriteRequest;
|
||||
import org.elasticsearch.client.ml.GetBucketsRequest;
|
||||
import org.elasticsearch.client.ml.GetBucketsResponse;
|
||||
import org.elasticsearch.client.ml.GetCategoriesRequest;
|
||||
import org.elasticsearch.client.ml.GetCategoriesResponse;
|
||||
import org.elasticsearch.client.ml.GetInfluencersRequest;
|
||||
import org.elasticsearch.client.ml.GetInfluencersResponse;
|
||||
import org.elasticsearch.client.ml.GetOverallBucketsRequest;
|
||||
|
@ -126,11 +128,150 @@ public class MachineLearningGetResultsIT extends ESRestHighLevelClientTestCase {
|
|||
bulkRequest.add(indexRequest);
|
||||
}
|
||||
|
||||
private void addCategoryIndexRequest(long categoryId, String categoryName, BulkRequest bulkRequest) {
|
||||
IndexRequest indexRequest = new IndexRequest(RESULTS_INDEX, DOC);
|
||||
indexRequest.source("{\"job_id\":\"" + JOB_ID + "\", \"category_id\": " + categoryId + ", \"terms\": \"" +
|
||||
categoryName + "\", \"regex\": \".*?" + categoryName + ".*\", \"max_matching_length\": 3, \"examples\": [\"" +
|
||||
categoryName + "\"]}", XContentType.JSON);
|
||||
bulkRequest.add(indexRequest);
|
||||
}
|
||||
|
||||
private void addCategoriesIndexRequests(BulkRequest bulkRequest) {
|
||||
|
||||
List<String> categories = Arrays.asList("AAL", "JZA", "JBU");
|
||||
|
||||
for (int i = 0; i < categories.size(); i++) {
|
||||
addCategoryIndexRequest(i+1, categories.get(i), bulkRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void deleteJob() throws IOException {
|
||||
new MlRestTestStateCleaner(logger, client()).clearMlMetadata();
|
||||
}
|
||||
|
||||
public void testGetCategories() throws IOException {
|
||||
|
||||
// index some category results
|
||||
BulkRequest bulkRequest = new BulkRequest();
|
||||
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||
|
||||
addCategoriesIndexRequests(bulkRequest);
|
||||
|
||||
highLevelClient().bulk(bulkRequest, RequestOptions.DEFAULT);
|
||||
|
||||
MachineLearningClient machineLearningClient = highLevelClient().machineLearning();
|
||||
|
||||
{
|
||||
GetCategoriesRequest request = new GetCategoriesRequest(JOB_ID);
|
||||
request.setPageParams(new PageParams(0, 10000));
|
||||
|
||||
GetCategoriesResponse response = execute(request, machineLearningClient::getCategories,
|
||||
machineLearningClient::getCategoriesAsync);
|
||||
|
||||
assertThat(response.count(), equalTo(3L));
|
||||
assertThat(response.categories().size(), equalTo(3));
|
||||
assertThat(response.categories().get(0).getCategoryId(), equalTo(1L));
|
||||
assertThat(response.categories().get(0).getGrokPattern(), equalTo(".*?AAL.*"));
|
||||
assertThat(response.categories().get(0).getRegex(), equalTo(".*?AAL.*"));
|
||||
assertThat(response.categories().get(0).getTerms(), equalTo("AAL"));
|
||||
|
||||
assertThat(response.categories().get(1).getCategoryId(), equalTo(2L));
|
||||
assertThat(response.categories().get(1).getGrokPattern(), equalTo(".*?JZA.*"));
|
||||
assertThat(response.categories().get(1).getRegex(), equalTo(".*?JZA.*"));
|
||||
assertThat(response.categories().get(1).getTerms(), equalTo("JZA"));
|
||||
|
||||
assertThat(response.categories().get(2).getCategoryId(), equalTo(3L));
|
||||
assertThat(response.categories().get(2).getGrokPattern(), equalTo(".*?JBU.*"));
|
||||
assertThat(response.categories().get(2).getRegex(), equalTo(".*?JBU.*"));
|
||||
assertThat(response.categories().get(2).getTerms(), equalTo("JBU"));
|
||||
}
|
||||
{
|
||||
GetCategoriesRequest request = new GetCategoriesRequest(JOB_ID);
|
||||
request.setPageParams(new PageParams(0, 1));
|
||||
|
||||
GetCategoriesResponse response = execute(request, machineLearningClient::getCategories,
|
||||
machineLearningClient::getCategoriesAsync);
|
||||
|
||||
assertThat(response.count(), equalTo(3L));
|
||||
assertThat(response.categories().size(), equalTo(1));
|
||||
assertThat(response.categories().get(0).getCategoryId(), equalTo(1L));
|
||||
assertThat(response.categories().get(0).getGrokPattern(), equalTo(".*?AAL.*"));
|
||||
assertThat(response.categories().get(0).getRegex(), equalTo(".*?AAL.*"));
|
||||
assertThat(response.categories().get(0).getTerms(), equalTo("AAL"));
|
||||
}
|
||||
{
|
||||
GetCategoriesRequest request = new GetCategoriesRequest(JOB_ID);
|
||||
request.setPageParams(new PageParams(1, 2));
|
||||
|
||||
GetCategoriesResponse response = execute(request, machineLearningClient::getCategories,
|
||||
machineLearningClient::getCategoriesAsync);
|
||||
|
||||
assertThat(response.count(), equalTo(3L));
|
||||
assertThat(response.categories().size(), equalTo(2));
|
||||
assertThat(response.categories().get(0).getCategoryId(), equalTo(2L));
|
||||
assertThat(response.categories().get(0).getGrokPattern(), equalTo(".*?JZA.*"));
|
||||
assertThat(response.categories().get(0).getRegex(), equalTo(".*?JZA.*"));
|
||||
assertThat(response.categories().get(0).getTerms(), equalTo("JZA"));
|
||||
|
||||
assertThat(response.categories().get(1).getCategoryId(), equalTo(3L));
|
||||
assertThat(response.categories().get(1).getGrokPattern(), equalTo(".*?JBU.*"));
|
||||
assertThat(response.categories().get(1).getRegex(), equalTo(".*?JBU.*"));
|
||||
assertThat(response.categories().get(1).getTerms(), equalTo("JBU"));
|
||||
}
|
||||
{
|
||||
GetCategoriesRequest request = new GetCategoriesRequest(JOB_ID);
|
||||
request.setCategoryId(0L); // request a non-existent category
|
||||
|
||||
GetCategoriesResponse response = execute(request, machineLearningClient::getCategories,
|
||||
machineLearningClient::getCategoriesAsync);
|
||||
|
||||
assertThat(response.count(), equalTo(0L));
|
||||
assertThat(response.categories().size(), equalTo(0));
|
||||
}
|
||||
{
|
||||
GetCategoriesRequest request = new GetCategoriesRequest(JOB_ID);
|
||||
request.setCategoryId(1L);
|
||||
|
||||
GetCategoriesResponse response = execute(request, machineLearningClient::getCategories,
|
||||
machineLearningClient::getCategoriesAsync);
|
||||
|
||||
assertThat(response.count(), equalTo(1L));
|
||||
assertThat(response.categories().size(), equalTo(1));
|
||||
assertThat(response.categories().get(0).getCategoryId(), equalTo(1L));
|
||||
assertThat(response.categories().get(0).getGrokPattern(), equalTo(".*?AAL.*"));
|
||||
assertThat(response.categories().get(0).getRegex(), equalTo(".*?AAL.*"));
|
||||
assertThat(response.categories().get(0).getTerms(), equalTo("AAL"));
|
||||
}
|
||||
{
|
||||
GetCategoriesRequest request = new GetCategoriesRequest(JOB_ID);
|
||||
request.setCategoryId(2L);
|
||||
|
||||
GetCategoriesResponse response = execute(request, machineLearningClient::getCategories,
|
||||
machineLearningClient::getCategoriesAsync);
|
||||
|
||||
assertThat(response.count(), equalTo(1L));
|
||||
assertThat(response.categories().get(0).getCategoryId(), equalTo(2L));
|
||||
assertThat(response.categories().get(0).getGrokPattern(), equalTo(".*?JZA.*"));
|
||||
assertThat(response.categories().get(0).getRegex(), equalTo(".*?JZA.*"));
|
||||
assertThat(response.categories().get(0).getTerms(), equalTo("JZA"));
|
||||
|
||||
}
|
||||
{
|
||||
GetCategoriesRequest request = new GetCategoriesRequest(JOB_ID);
|
||||
request.setCategoryId(3L);
|
||||
|
||||
GetCategoriesResponse response = execute(request, machineLearningClient::getCategories,
|
||||
machineLearningClient::getCategoriesAsync);
|
||||
|
||||
assertThat(response.count(), equalTo(1L));
|
||||
assertThat(response.categories().get(0).getCategoryId(), equalTo(3L));
|
||||
assertThat(response.categories().get(0).getGrokPattern(), equalTo(".*?JBU.*"));
|
||||
assertThat(response.categories().get(0).getRegex(), equalTo(".*?JBU.*"));
|
||||
assertThat(response.categories().get(0).getTerms(), equalTo("JBU"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetBuckets() throws IOException {
|
||||
MachineLearningClient machineLearningClient = highLevelClient().machineLearning();
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ import org.elasticsearch.client.ml.ForecastJobRequest;
|
|||
import org.elasticsearch.client.ml.ForecastJobResponse;
|
||||
import org.elasticsearch.client.ml.GetBucketsRequest;
|
||||
import org.elasticsearch.client.ml.GetBucketsResponse;
|
||||
import org.elasticsearch.client.ml.GetCategoriesRequest;
|
||||
import org.elasticsearch.client.ml.GetCategoriesResponse;
|
||||
import org.elasticsearch.client.ml.GetInfluencersRequest;
|
||||
import org.elasticsearch.client.ml.GetInfluencersResponse;
|
||||
import org.elasticsearch.client.ml.GetJobRequest;
|
||||
|
@ -69,6 +71,7 @@ import org.elasticsearch.client.ml.job.config.Operator;
|
|||
import org.elasticsearch.client.ml.job.config.RuleCondition;
|
||||
import org.elasticsearch.client.ml.job.results.AnomalyRecord;
|
||||
import org.elasticsearch.client.ml.job.results.Bucket;
|
||||
import org.elasticsearch.client.ml.job.results.CategoryDefinition;
|
||||
import org.elasticsearch.client.ml.job.results.Influencer;
|
||||
import org.elasticsearch.client.ml.job.results.OverallBucket;
|
||||
import org.elasticsearch.client.ml.job.stats.JobStats;
|
||||
|
@ -473,7 +476,7 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testGetBuckets() throws IOException, InterruptedException {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
|
@ -1111,4 +1114,74 @@ public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetCategories() throws IOException, InterruptedException {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
String jobId = "test-get-categories";
|
||||
Job job = MachineLearningIT.buildJob(jobId);
|
||||
client.machineLearning().putJob(new PutJobRequest(job), RequestOptions.DEFAULT);
|
||||
|
||||
// Let us index a category
|
||||
IndexRequest indexRequest = new IndexRequest(".ml-anomalies-shared", "doc");
|
||||
indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||
indexRequest.source("{\"job_id\": \"test-get-categories\", \"category_id\": 1, \"terms\": \"AAL\"," +
|
||||
" \"regex\": \".*?AAL.*\", \"max_matching_length\": 3, \"examples\": [\"AAL\"]}", XContentType.JSON);
|
||||
client.index(indexRequest, RequestOptions.DEFAULT);
|
||||
|
||||
{
|
||||
// tag::x-pack-ml-get-categories-request
|
||||
GetCategoriesRequest request = new GetCategoriesRequest(jobId); // <1>
|
||||
// end::x-pack-ml-get-categories-request
|
||||
|
||||
// tag::x-pack-ml-get-categories-category-id
|
||||
request.setCategoryId(1L); // <1>
|
||||
// end::x-pack-ml-get-categories-category-id
|
||||
|
||||
// tag::x-pack-ml-get-categories-page
|
||||
request.setPageParams(new PageParams(100, 200)); // <1>
|
||||
// end::x-pack-ml-get-categories-page
|
||||
|
||||
// Set page params back to null so the response contains the category we indexed
|
||||
request.setPageParams(null);
|
||||
|
||||
// tag::x-pack-ml-get-categories-execute
|
||||
GetCategoriesResponse response = client.machineLearning().getCategories(request, RequestOptions.DEFAULT);
|
||||
// end::x-pack-ml-get-categories-execute
|
||||
|
||||
// tag::x-pack-ml-get-categories-response
|
||||
long count = response.count(); // <1>
|
||||
List<CategoryDefinition> categories = response.categories(); // <2>
|
||||
// end::x-pack-ml-get-categories-response
|
||||
assertEquals(1, categories.size());
|
||||
}
|
||||
{
|
||||
GetCategoriesRequest request = new GetCategoriesRequest(jobId);
|
||||
|
||||
// tag::x-pack-ml-get-categories-listener
|
||||
ActionListener<GetCategoriesResponse> listener =
|
||||
new ActionListener<GetCategoriesResponse>() {
|
||||
@Override
|
||||
public void onResponse(GetCategoriesResponse getcategoriesResponse) {
|
||||
// <1>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
// <2>
|
||||
}
|
||||
};
|
||||
// end::x-pack-ml-get-categories-listener
|
||||
|
||||
// Replace the empty listener by a blocking listener in test
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
listener = new LatchedActionListener<>(listener, latch);
|
||||
|
||||
// tag::x-pack-ml-get-categories-execute-async
|
||||
client.machineLearning().getCategoriesAsync(request, RequestOptions.DEFAULT, listener); // <1>
|
||||
// end::x-pack-ml-get-categories-execute-async
|
||||
|
||||
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.elasticsearch.client.ml;
|
||||
|
||||
import org.elasticsearch.client.ml.job.util.PageParams;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GetCategoriesRequestTests extends AbstractXContentTestCase<GetCategoriesRequest> {
|
||||
|
||||
@Override
|
||||
protected GetCategoriesRequest createTestInstance() {
|
||||
GetCategoriesRequest request = new GetCategoriesRequest(randomAlphaOfLengthBetween(1, 20));
|
||||
if (randomBoolean()) {
|
||||
request.setCategoryId(randomNonNegativeLong());
|
||||
} else {
|
||||
int from = randomInt(10000);
|
||||
int size = randomInt(10000);
|
||||
request.setPageParams(new PageParams(from, size));
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetCategoriesRequest doParseInstance(XContentParser parser) throws IOException {
|
||||
return GetCategoriesRequest.PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnknownFields() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.elasticsearch.client.ml;
|
||||
|
||||
import org.elasticsearch.client.ml.job.results.CategoryDefinition;
|
||||
import org.elasticsearch.client.ml.job.results.CategoryDefinitionTests;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.test.AbstractXContentTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GetCategoriesResponseTests extends AbstractXContentTestCase<GetCategoriesResponse> {
|
||||
|
||||
@Override
|
||||
protected GetCategoriesResponse createTestInstance() {
|
||||
String jobId = randomAlphaOfLength(20);
|
||||
int listSize = randomInt(10);
|
||||
List<CategoryDefinition> categories = new ArrayList<>(listSize);
|
||||
for (int j = 0; j < listSize; j++) {
|
||||
CategoryDefinition category = CategoryDefinitionTests.createTestInstance(jobId);
|
||||
categories.add(category);
|
||||
}
|
||||
return new GetCategoriesResponse(categories, listSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetCategoriesResponse doParseInstance(XContentParser parser) throws IOException {
|
||||
return GetCategoriesResponse.fromXContent(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUnknownFields() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ import java.util.Arrays;
|
|||
|
||||
public class CategoryDefinitionTests extends AbstractXContentTestCase<CategoryDefinition> {
|
||||
|
||||
public CategoryDefinition createTestInstance(String jobId) {
|
||||
public static CategoryDefinition createTestInstance(String jobId) {
|
||||
CategoryDefinition categoryDefinition = new CategoryDefinition(jobId);
|
||||
categoryDefinition.setCategoryId(randomLong());
|
||||
categoryDefinition.setTerms(randomAlphaOfLength(10));
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
[[java-rest-high-x-pack-ml-get-categories]]
|
||||
=== Get Categories API
|
||||
|
||||
The Get Categories API retrieves one or more category results.
|
||||
It accepts a `GetCategoriesRequest` object and responds
|
||||
with a `GetCategoriesResponse` object.
|
||||
|
||||
[[java-rest-high-x-pack-ml-get-categories-request]]
|
||||
==== Get Categories Request
|
||||
|
||||
A `GetCategoriesRequest` object gets created with an existing non-null `jobId`.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-categories-request]
|
||||
--------------------------------------------------
|
||||
<1> Constructing a new request referencing an existing `jobId`
|
||||
|
||||
==== Optional Arguments
|
||||
The following arguments are optional:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-categories-category-id]
|
||||
--------------------------------------------------
|
||||
<1> The id of the category to get. Otherwise it will return all categories.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-categories-page]
|
||||
--------------------------------------------------
|
||||
<1> The page parameters `from` and `size`. `from` specifies the number of categories to skip.
|
||||
`size` specifies the maximum number of categories to get. Defaults to `0` and `100` respectively.
|
||||
|
||||
[[java-rest-high-x-pack-ml-get-categories-execution]]
|
||||
==== Execution
|
||||
|
||||
The request can be executed through the `MachineLearningClient` contained
|
||||
in the `RestHighLevelClient` object, accessed via the `machineLearningClient()` method.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-categories-execute]
|
||||
--------------------------------------------------
|
||||
|
||||
|
||||
[[java-rest-high-x-pack-ml-get-categories-execution-async]]
|
||||
==== Asynchronous Execution
|
||||
|
||||
The request can also be executed asynchronously:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-categories-execute-async]
|
||||
--------------------------------------------------
|
||||
<1> The `GetCategoriesRequest` to execute and the `ActionListener` to use when
|
||||
the execution completes
|
||||
|
||||
The asynchronous method does not block and returns immediately. Once it is
|
||||
completed the `ActionListener` is called back with the `onResponse` method
|
||||
if the execution is successful or the `onFailure` method if the execution
|
||||
failed.
|
||||
|
||||
A typical listener for `GetCategoriesResponse` looks like:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-categories-listener]
|
||||
--------------------------------------------------
|
||||
<1> `onResponse` is called back when the action is completed successfully
|
||||
<2> `onFailure` is called back when some unexpected error occurs
|
||||
|
||||
[[java-rest-high-snapshot-ml-get-categories-response]]
|
||||
==== Get Categories Response
|
||||
|
||||
The returned `GetCategoriesResponse` contains the requested categories:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/MlClientDocumentationIT.java[x-pack-ml-get-categories-response]
|
||||
--------------------------------------------------
|
||||
<1> The count of categories that were matched
|
||||
<2> The categories retrieved
|
|
@ -226,6 +226,7 @@ The Java High Level REST Client supports the following Machine Learning APIs:
|
|||
* <<java-rest-high-x-pack-ml-get-records>>
|
||||
* <<java-rest-high-x-pack-ml-post-data>>
|
||||
* <<java-rest-high-x-pack-ml-get-influencers>>
|
||||
* <<java-rest-high-x-pack-ml-get-categories>>
|
||||
|
||||
include::ml/put-job.asciidoc[]
|
||||
include::ml/get-job.asciidoc[]
|
||||
|
@ -241,6 +242,7 @@ include::ml/get-overall-buckets.asciidoc[]
|
|||
include::ml/get-records.asciidoc[]
|
||||
include::ml/post-data.asciidoc[]
|
||||
include::ml/get-influencers.asciidoc[]
|
||||
include::ml/get-categories.asciidoc[]
|
||||
|
||||
== Migration APIs
|
||||
|
||||
|
|
Loading…
Reference in New Issue