Skip to content

Commit aaed6b5

Browse files
author
Hendrik Muhs
authored
[7.x][Transform] add support for missing bucket (#59591) (#60390)
add support for "missing_bucket" in group_by fixes #42941 fixes #55102 backport #59591
1 parent 00a1949 commit aaed6b5

File tree

36 files changed

+742
-262
lines changed

36 files changed

+742
-262
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/transform/transforms/pivot/DateHistogramGroupSource.java

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,10 @@ public int hashCode() {
188188
(args) -> {
189189
String field = (String) args[0];
190190
Script script = (Script) args[1];
191-
String fixedInterval = (String) args[2];
192-
String calendarInterval = (String) args[3];
193-
ZoneId zoneId = (ZoneId) args[4];
191+
boolean missingBucket = args[2] == null ? false : (boolean) args[2];
192+
String fixedInterval = (String) args[3];
193+
String calendarInterval = (String) args[4];
194+
ZoneId zoneId = (ZoneId) args[5];
194195

195196
Interval interval = null;
196197

@@ -204,13 +205,14 @@ public int hashCode() {
204205
throw new IllegalArgumentException("You must specify either fixed_interval or calendar_interval, found none");
205206
}
206207

207-
return new DateHistogramGroupSource(field, script, interval, zoneId);
208+
return new DateHistogramGroupSource(field, script, missingBucket, interval, zoneId);
208209
}
209210
);
210211

211212
static {
212213
PARSER.declareString(optionalConstructorArg(), FIELD);
213214
Script.declareScript(PARSER, optionalConstructorArg(), SCRIPT);
215+
PARSER.declareBoolean(optionalConstructorArg(), MISSING_BUCKET);
214216
PARSER.declareString(optionalConstructorArg(), new ParseField(FixedInterval.NAME));
215217
PARSER.declareString(optionalConstructorArg(), new ParseField(CalendarInterval.NAME));
216218

@@ -231,7 +233,11 @@ public static DateHistogramGroupSource fromXContent(final XContentParser parser)
231233
private final ZoneId timeZone;
232234

233235
DateHistogramGroupSource(String field, Script script, Interval interval, ZoneId timeZone) {
234-
super(field, script);
236+
this(field, script, false, interval, timeZone);
237+
}
238+
239+
DateHistogramGroupSource(String field, Script script, boolean missingBucket, Interval interval, ZoneId timeZone) {
240+
super(field, script, missingBucket);
235241
this.interval = interval;
236242
this.timeZone = timeZone;
237243
}
@@ -273,14 +279,16 @@ public boolean equals(Object other) {
273279

274280
final DateHistogramGroupSource that = (DateHistogramGroupSource) other;
275281

276-
return Objects.equals(this.field, that.field)
282+
return this.missingBucket == that.missingBucket
283+
&& Objects.equals(this.field, that.field)
284+
&& Objects.equals(this.script, that.script)
277285
&& Objects.equals(this.interval, that.interval)
278286
&& Objects.equals(this.timeZone, that.timeZone);
279287
}
280288

281289
@Override
282290
public int hashCode() {
283-
return Objects.hash(field, interval, timeZone);
291+
return Objects.hash(field, script, missingBucket, interval, timeZone);
284292
}
285293

286294
@Override
@@ -298,6 +306,7 @@ public static class Builder {
298306
private Script script;
299307
private Interval interval;
300308
private ZoneId timeZone;
309+
private boolean missingBucket;
301310

302311
/**
303312
* The field with which to construct the date histogram grouping
@@ -339,8 +348,18 @@ public Builder setTimeZone(ZoneId timeZone) {
339348
return this;
340349
}
341350

351+
/**
352+
* Sets the value of "missing_bucket"
353+
* @param missingBucket value of "missing_bucket" to be set
354+
* @return The {@link Builder} with "missing_bucket" set.
355+
*/
356+
public Builder setMissingBucket(boolean missingBucket) {
357+
this.missingBucket = missingBucket;
358+
return this;
359+
}
360+
342361
public DateHistogramGroupSource build() {
343-
return new DateHistogramGroupSource(field, script, interval, timeZone);
362+
return new DateHistogramGroupSource(field, script, missingBucket, interval, timeZone);
344363
}
345364
}
346365
}

client/rest-high-level/src/main/java/org/elasticsearch/client/transform/transforms/pivot/GeoTileGroupSource.java

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,18 @@ public class GeoTileGroupSource extends SingleGroupSource implements ToXContentO
4040
private static final String NAME = "transform_geo_tile_group";
4141

4242
private static final ParseField PRECISION = new ParseField("precision");
43-
private static final ConstructingObjectParser<GeoTileGroupSource, Void> PARSER = new ConstructingObjectParser<>(NAME, true, (args) -> {
43+
private static final ConstructingObjectParser<GeoTileGroupSource, Void> PARSER = new ConstructingObjectParser<>(NAME, true, (args) -> {
4444
String field = (String) args[0];
45-
Integer precision = (Integer) args[1];
46-
GeoBoundingBox boundingBox = (GeoBoundingBox) args[2];
45+
boolean missingBucket = args[1] == null ? false : (boolean) args[1];
46+
Integer precision = (Integer) args[2];
47+
GeoBoundingBox boundingBox = (GeoBoundingBox) args[3];
4748

48-
return new GeoTileGroupSource(field, precision, boundingBox);
49+
return new GeoTileGroupSource(field, missingBucket, precision, boundingBox);
4950
});
5051

5152
static {
5253
PARSER.declareString(optionalConstructorArg(), FIELD);
54+
PARSER.declareBoolean(optionalConstructorArg(), MISSING_BUCKET);
5355
PARSER.declareInt(optionalConstructorArg(), PRECISION);
5456
PARSER.declareField(
5557
optionalConstructorArg(),
@@ -62,7 +64,11 @@ public class GeoTileGroupSource extends SingleGroupSource implements ToXContentO
6264
private final GeoBoundingBox geoBoundingBox;
6365

6466
public GeoTileGroupSource(final String field, final Integer precision, final GeoBoundingBox boundingBox) {
65-
super(field, null);
67+
this(field, false, precision, boundingBox);
68+
}
69+
70+
public GeoTileGroupSource(final String field, final boolean missingBucket, final Integer precision, final GeoBoundingBox boundingBox) {
71+
super(field, null, missingBucket);
6672
if (precision != null) {
6773
GeoTileUtils.checkPrecisionRange(precision);
6874
}
@@ -113,14 +119,66 @@ public boolean equals(Object other) {
113119

114120
final GeoTileGroupSource that = (GeoTileGroupSource) other;
115121

116-
return Objects.equals(this.field, that.field)
122+
return this.missingBucket == that.missingBucket
123+
&& Objects.equals(this.field, that.field)
117124
&& Objects.equals(this.precision, that.precision)
118125
&& Objects.equals(this.geoBoundingBox, that.geoBoundingBox);
119126
}
120127

121128
@Override
122129
public int hashCode() {
123-
return Objects.hash(field, precision, geoBoundingBox);
130+
return Objects.hash(field, missingBucket, precision, geoBoundingBox);
124131
}
125132

133+
public static class Builder {
134+
135+
private String field;
136+
private boolean missingBucket;
137+
private Integer precision;
138+
private GeoBoundingBox boundingBox;
139+
140+
/**
141+
* The field with which to construct the geo tile grouping
142+
* @param field The field name
143+
* @return The {@link Builder} with the field set.
144+
*/
145+
public Builder setField(String field) {
146+
this.field = field;
147+
return this;
148+
}
149+
150+
/**
151+
* Sets the value of "missing_bucket"
152+
* @param missingBucket value of "missing_bucket" to be set
153+
* @return The {@link Builder} with "missing_bucket" set.
154+
*/
155+
public Builder setMissingBucket(boolean missingBucket) {
156+
this.missingBucket = missingBucket;
157+
return this;
158+
}
159+
160+
/**
161+
* The precision with which to construct the geo tile grouping
162+
* @param precision The precision
163+
* @return The {@link Builder} with the precision set.
164+
*/
165+
public Builder setPrecission(Integer precision) {
166+
this.precision = precision;
167+
return this;
168+
}
169+
170+
/**
171+
* Set the bounding box for the geo tile grouping
172+
* @param boundingBox The bounding box
173+
* @return the {@link Builder} with the bounding box set.
174+
*/
175+
public Builder setBoundingBox(GeoBoundingBox boundingBox) {
176+
this.boundingBox = boundingBox;
177+
return this;
178+
}
179+
180+
public GeoTileGroupSource build() {
181+
return new GeoTileGroupSource(field, missingBucket, precision, boundingBox);
182+
}
183+
}
126184
}

client/rest-high-level/src/main/java/org/elasticsearch/client/transform/transforms/pivot/HistogramGroupSource.java

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ public class HistogramGroupSource extends SingleGroupSource implements ToXConten
4141
private static final ConstructingObjectParser<HistogramGroupSource, Void> PARSER = new ConstructingObjectParser<>(
4242
"histogram_group_source",
4343
true,
44-
args -> new HistogramGroupSource((String) args[0], (Script) args[1], (double) args[2])
44+
args -> new HistogramGroupSource((String) args[0], (Script) args[1], args[2] == null ? false : (boolean) args[2], (double) args[3])
4545
);
4646

4747
static {
4848
PARSER.declareString(optionalConstructorArg(), FIELD);
4949
Script.declareScript(PARSER, optionalConstructorArg(), SCRIPT);
50+
PARSER.declareBoolean(optionalConstructorArg(), MISSING_BUCKET);
5051
PARSER.declareDouble(optionalConstructorArg(), INTERVAL);
5152
}
5253

@@ -57,7 +58,11 @@ public static HistogramGroupSource fromXContent(final XContentParser parser) {
5758
private final double interval;
5859

5960
HistogramGroupSource(String field, Script script, double interval) {
60-
super(field, script);
61+
this(field, script, false, interval);
62+
}
63+
64+
HistogramGroupSource(String field, Script script, boolean missingBucket, double interval) {
65+
super(field, script, missingBucket);
6166
if (interval <= 0) {
6267
throw new IllegalArgumentException("[interval] must be greater than 0.");
6368
}
@@ -94,12 +99,15 @@ public boolean equals(Object other) {
9499

95100
final HistogramGroupSource that = (HistogramGroupSource) other;
96101

97-
return Objects.equals(this.field, that.field) && Objects.equals(this.interval, that.interval);
102+
return this.missingBucket == that.missingBucket
103+
&& Objects.equals(this.field, that.field)
104+
&& Objects.equals(this.script, that.script)
105+
&& Objects.equals(this.interval, that.interval);
98106
}
99107

100108
@Override
101109
public int hashCode() {
102-
return Objects.hash(field, interval);
110+
return Objects.hash(field, script, interval, missingBucket);
103111
}
104112

105113
public static Builder builder() {
@@ -110,6 +118,7 @@ public static class Builder {
110118

111119
private String field;
112120
private Script script;
121+
private boolean missingBucket;
113122
private double interval;
114123

115124
/**
@@ -123,7 +132,7 @@ public Builder setField(String field) {
123132
}
124133

125134
/**
126-
* Set the interval for the histogram aggregation
135+
* Set the interval for the histogram grouping
127136
* @param interval The numeric interval for the histogram grouping
128137
* @return The {@link Builder} with the interval set.
129138
*/
@@ -142,8 +151,18 @@ public Builder setScript(Script script) {
142151
return this;
143152
}
144153

154+
/**
155+
* Sets the value of "missing_bucket"
156+
* @param missingBucket value of "missing_bucket" to be set
157+
* @return The {@link Builder} with "missing_bucket" set.
158+
*/
159+
public Builder setMissingBucket(boolean missingBucket) {
160+
this.missingBucket = missingBucket;
161+
return this;
162+
}
163+
145164
public HistogramGroupSource build() {
146-
return new HistogramGroupSource(field, script, interval);
165+
return new HistogramGroupSource(field, script, missingBucket, interval);
147166
}
148167
}
149168
}

client/rest-high-level/src/main/java/org/elasticsearch/client/transform/transforms/pivot/SingleGroupSource.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public abstract class SingleGroupSource implements ToXContentObject {
3232

3333
protected static final ParseField FIELD = new ParseField("field");
3434
protected static final ParseField SCRIPT = new ParseField("script");
35+
protected static final ParseField MISSING_BUCKET = new ParseField("missing_bucket");
3536

3637
public enum Type {
3738
TERMS,
@@ -46,10 +47,12 @@ public String value() {
4647

4748
protected final String field;
4849
protected final Script script;
50+
protected final boolean missingBucket;
4951

50-
public SingleGroupSource(final String field, final Script script) {
52+
public SingleGroupSource(final String field, final Script script, final boolean missingBucket) {
5153
this.field = field;
5254
this.script = script;
55+
this.missingBucket = missingBucket;
5356
}
5457

5558
public abstract Type getType();
@@ -62,13 +65,20 @@ public Script getScript() {
6265
return script;
6366
}
6467

68+
public boolean getMissingBucket() {
69+
return missingBucket;
70+
}
71+
6572
protected void innerXContent(XContentBuilder builder, Params params) throws IOException {
6673
if (field != null) {
6774
builder.field(FIELD.getPreferredName(), field);
6875
}
6976
if (script != null) {
7077
builder.field(SCRIPT.getPreferredName(), script);
7178
}
79+
if (missingBucket) {
80+
builder.field(MISSING_BUCKET.getPreferredName(), missingBucket);
81+
}
7282
}
7383

7484
@Override
@@ -83,11 +93,13 @@ public boolean equals(Object other) {
8393

8494
final SingleGroupSource that = (SingleGroupSource) other;
8595

86-
return Objects.equals(this.field, that.field) && Objects.equals(this.script, that.script);
96+
return this.missingBucket == that.missingBucket
97+
&& Objects.equals(this.field, that.field)
98+
&& Objects.equals(this.script, that.script);
8799
}
88100

89101
@Override
90102
public int hashCode() {
91-
return Objects.hash(field, script);
103+
return Objects.hash(field, script, missingBucket);
92104
}
93105
}

client/rest-high-level/src/main/java/org/elasticsearch/client/transform/transforms/pivot/TermsGroupSource.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,25 @@ public class TermsGroupSource extends SingleGroupSource implements ToXContentObj
3535
private static final ConstructingObjectParser<TermsGroupSource, Void> PARSER = new ConstructingObjectParser<>(
3636
"terms_group_source",
3737
true,
38-
args -> new TermsGroupSource((String) args[0], (Script) args[1])
38+
args -> new TermsGroupSource((String) args[0], (Script) args[1], args[2] == null ? false : (boolean) args[2])
3939
);
4040

4141
static {
4242
PARSER.declareString(optionalConstructorArg(), FIELD);
4343
Script.declareScript(PARSER, optionalConstructorArg(), SCRIPT);
44+
PARSER.declareBoolean(optionalConstructorArg(), MISSING_BUCKET);
4445
}
4546

4647
public static TermsGroupSource fromXContent(final XContentParser parser) {
4748
return PARSER.apply(parser, null);
4849
}
4950

5051
TermsGroupSource(final String field, final Script script) {
51-
super(field, script);
52+
this(field, script, false);
53+
}
54+
55+
TermsGroupSource(final String field, final Script script, final boolean missingBucket) {
56+
super(field, script, missingBucket);
5257
}
5358

5459
@Override
@@ -72,9 +77,10 @@ public static class Builder {
7277

7378
private String field;
7479
private Script script;
80+
private boolean missingBucket;
7581

7682
/**
77-
* The field with which to construct the date histogram grouping
83+
* The field with which to construct the terms grouping
7884
* @param field The field name
7985
* @return The {@link Builder} with the field set.
8086
*/
@@ -93,8 +99,18 @@ public Builder setScript(Script script) {
9399
return this;
94100
}
95101

102+
/**
103+
* Sets the value of "missing_bucket"
104+
* @param missingBucket value of "missing_bucket" to be set
105+
* @return The {@link Builder} with "missing_bucket" set.
106+
*/
107+
public Builder setMissingBucket(boolean missingBucket) {
108+
this.missingBucket = missingBucket;
109+
return this;
110+
}
111+
96112
public TermsGroupSource build() {
97-
return new TermsGroupSource(field, script);
113+
return new TermsGroupSource(field, script, missingBucket);
98114
}
99115
}
100116
}

0 commit comments

Comments
 (0)