Skip to content

Commit 860e03a

Browse files
author
Hendrik Muhs
committed
[Transform] add support for "missing" aggregation (#63651)
add support for the missing (bucket) aggregation (counts docs with a configured missing field value) in transform. The output is mapped to name:count, the mapping type is long.
1 parent 4c333f9 commit 860e03a

File tree

4 files changed

+35
-5
lines changed

4 files changed

+35
-5
lines changed

docs/reference/rest-api/common-parms.asciidoc

+1
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ supported:
682682
* <<search-aggregations-metrics-geocentroid-aggregation,Geo centroid>>
683683
* <<search-aggregations-metrics-max-aggregation,Max>>
684684
* <<search-aggregations-metrics-min-aggregation,Min>>
685+
* <<search-aggregations-bucket-missing-aggregation,Missing>>
685686
* <<search-aggregations-metrics-percentile-aggregation,Percentiles>>
686687
* <<search-aggregations-bucket-rare-terms-aggregation, Rare Terms>>
687688
* <<search-aggregations-metrics-scripted-metric-aggregation,Scripted metric>>

x-pack/plugin/transform/qa/single-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/transform/integration/TransformPivotRestIT.java

+3
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,13 @@ public void testSimplePivot() throws Exception {
8787

8888
// get and check some users
8989
assertOnePivotValue(transformIndex + "/_search?q=reviewer:user_0", 3.776978417);
90+
assertOneCount(transformIndex + "/_search?q=reviewer:user_0", "hits.hits._source.affiliate_missing", 0);
9091
assertOnePivotValue(transformIndex + "/_search?q=reviewer:user_5", 3.72);
92+
assertOneCount(transformIndex + "/_search?q=reviewer:user_5", "hits.hits._source.affiliate_missing", 25);
9193
assertOnePivotValue(transformIndex + "/_search?q=reviewer:user_11", 3.846153846);
9294
assertOnePivotValue(transformIndex + "/_search?q=reviewer:user_20", 3.769230769);
9395
assertOnePivotValue(transformIndex + "/_search?q=reviewer:user_26", 3.918918918);
96+
assertOneCount(transformIndex + "/_search?q=reviewer:user_26", "hits.hits._source.affiliate_missing", 0);
9497
}
9598

9699
public void testSimpleDataStreamPivot() throws Exception {

x-pack/plugin/transform/qa/single-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/transform/integration/TransformRestTestCase.java

+29-3
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ protected void createReviewsIndex(
101101
long user = Math.round(Math.pow(i * 31 % 1000, distributionTable[i % distributionTable.length]) % 27);
102102
int stars = distributionTable[(i * 33) % distributionTable.length];
103103
long business = Math.round(Math.pow(user * stars, distributionTable[i % distributionTable.length]) % 13);
104+
long affiliate = Math.round(Math.pow(user * stars, distributionTable[i % distributionTable.length]) % 11);
105+
104106
if (i % 12 == 0) {
105107
hour = 10 + (i % 13);
106108
}
@@ -133,6 +135,9 @@ protected void createReviewsIndex(
133135
if ((user == userWithMissingBuckets && missingBucketField.equals("timestamp")) == false) {
134136
bulk.append("\"timestamp\":\"").append(date_string).append("\",");
135137
}
138+
if ((user == userWithMissingBuckets && missingBucketField.equals("affiliate_id")) == false) {
139+
bulk.append("\"affiliate_id\":\"").append("affiliate_").append(affiliate).append("\",");
140+
}
136141

137142
// always add @timestamp to avoid complicated logic regarding ','
138143
bulk.append("\"@timestamp\":\"").append(date_string).append("\"");
@@ -185,6 +190,9 @@ protected void putReviewsIndex(String indexName, String dateType, boolean isData
185190
.startObject("location")
186191
.field("type", "geo_point")
187192
.endObject()
193+
.startObject("affiliate_id")
194+
.field("type", "keyword")
195+
.endObject()
188196
.endObject()
189197
.endObject();
190198
}
@@ -221,7 +229,7 @@ protected void createReviewsIndex() throws IOException {
221229
}
222230

223231
protected void createReviewsIndex(String indexName) throws IOException {
224-
createReviewsIndex(indexName, 1000, "date", false, -1, null);
232+
createReviewsIndex(indexName, 1000, "date", false, 5, "affiliate_id");
225233
}
226234

227235
protected void createPivotReviewsTransform(String transformId, String transformIndex, String query) throws IOException {
@@ -298,6 +306,11 @@ protected void createPivotReviewsTransform(
298306
+ " \"avg_rating\": {"
299307
+ " \"avg\": {"
300308
+ " \"field\": \"stars\""
309+
+ " } },"
310+
+ " \"affiliate_missing\": {"
311+
+ " \"missing\": {"
312+
+ " \"field\": \"affiliate_id\""
313+
301314
+ " } } } },"
302315
+ "\"frequency\":\"1s\""
303316
+ "}";
@@ -480,8 +493,13 @@ public void wipeTransforms() throws IOException {
480493

481494
// the configuration index should be empty
482495
Request request = new Request("GET", TransformInternalIndexConstants.LATEST_INDEX_NAME + "/_search");
483-
request.setOptions(expectWarnings("this request accesses system indices: [" + TransformInternalIndexConstants.LATEST_INDEX_NAME +
484-
"], but in a future major version, direct access to system indices will be prevented by default"));
496+
request.setOptions(
497+
expectWarnings(
498+
"this request accesses system indices: ["
499+
+ TransformInternalIndexConstants.LATEST_INDEX_NAME
500+
+ "], but in a future major version, direct access to system indices will be prevented by default"
501+
)
502+
);
485503
try {
486504
Response searchResponse = adminClient().performRequest(request);
487505
Map<String, Object> searchResult = entityAsMap(searchResponse);
@@ -541,6 +559,14 @@ protected void assertOnePivotValue(String query, double expected) throws IOExcep
541559
assertEquals(expected, actual, 0.000001);
542560
}
543561

562+
protected void assertOneCount(String query, String field, int expected) throws IOException {
563+
Map<String, Object> searchResult = getAsMap(query);
564+
565+
assertEquals(1, XContentMapValues.extractValue("hits.total.value", searchResult));
566+
int actual = (Integer) ((List<?>) XContentMapValues.extractValue(field, searchResult)).get(0);
567+
assertEquals(expected, actual);
568+
}
569+
544570
protected static String getTransformEndpoint() {
545571
return useDeprecatedEndpoints ? TransformField.REST_BASE_PATH_TRANSFORMS_DEPRECATED : TransformField.REST_BASE_PATH_TRANSFORMS;
546572
}

x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/transforms/pivot/TransformAggregations.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public final class TransformAggregations {
6666
"ip_range",
6767
"matrix_stats",
6868
"median_absolute_deviation",
69-
"missing",
7069
"nested",
7170
"percentile_ranks",
7271
"range",
@@ -110,7 +109,8 @@ enum AggregationType {
110109
PERCENTILES("percentiles", DOUBLE),
111110
FILTER("filter", LONG),
112111
TERMS("terms", FLATTENED),
113-
RARE_TERMS("rare_terms", FLATTENED);
112+
RARE_TERMS("rare_terms", FLATTENED),
113+
MISSING("missing", LONG);
114114

115115
private final String aggregationType;
116116
private final String targetMapping;

0 commit comments

Comments
 (0)