Skip to content

Commit fd3051c

Browse files
committed
Initial work on adding multi-field for all string type fields
1 parent feafb3a commit fd3051c

File tree

4 files changed

+134
-15
lines changed

4 files changed

+134
-15
lines changed

test/framework/src/main/java/org/elasticsearch/datageneration/FieldType.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import org.elasticsearch.datageneration.fields.leaf.IpFieldDataGenerator;
2424
import org.elasticsearch.datageneration.fields.leaf.KeywordFieldDataGenerator;
2525
import org.elasticsearch.datageneration.fields.leaf.LongFieldDataGenerator;
26+
import org.elasticsearch.datageneration.fields.leaf.MatchOnlyTextFieldDataGenerator;
27+
import org.elasticsearch.datageneration.fields.leaf.PatternedTextFieldDataGenerator;
2628
import org.elasticsearch.datageneration.fields.leaf.ScaledFloatFieldDataGenerator;
2729
import org.elasticsearch.datageneration.fields.leaf.ShortFieldDataGenerator;
2830
import org.elasticsearch.datageneration.fields.leaf.TextFieldDataGenerator;
@@ -50,7 +52,9 @@ public enum FieldType {
5052
TEXT("text"),
5153
IP("ip"),
5254
CONSTANT_KEYWORD("constant_keyword"),
53-
WILDCARD("wildcard");
55+
WILDCARD("wildcard"),
56+
MATCH_ONLY_TEXT("match_only_text"),
57+
PATTERNED_TEXT("patterned_text");
5458

5559
private final String name;
5660

@@ -78,6 +82,8 @@ public FieldDataGenerator generator(String fieldName, DataSource dataSource) {
7882
case IP -> new IpFieldDataGenerator(dataSource);
7983
case CONSTANT_KEYWORD -> new ConstantKeywordFieldDataGenerator();
8084
case WILDCARD -> new WildcardFieldDataGenerator(dataSource);
85+
case MATCH_ONLY_TEXT -> new MatchOnlyTextFieldDataGenerator(dataSource);
86+
case PATTERNED_TEXT -> new PatternedTextFieldDataGenerator(dataSource);
8187
};
8288
}
8389

@@ -101,6 +107,8 @@ public static FieldType tryParse(String name) {
101107
case "ip" -> FieldType.IP;
102108
case "constant_keyword" -> FieldType.CONSTANT_KEYWORD;
103109
case "wildcard" -> FieldType.WILDCARD;
110+
case "match_only_text" -> FieldType.MATCH_ONLY_TEXT;
111+
case "patterned_text" -> FieldType.PATTERNED_TEXT;
104112
default -> null;
105113
};
106114
}

test/framework/src/main/java/org/elasticsearch/datageneration/datasource/DefaultMappingParametersHandler.java

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
import org.elasticsearch.geometry.utils.WellKnownText;
1616
import org.elasticsearch.index.mapper.Mapper;
1717
import org.elasticsearch.index.mapper.ObjectMapper;
18+
import org.elasticsearch.script.field.Field;
1819
import org.elasticsearch.test.ESTestCase;
1920

2021
import java.time.Instant;
2122
import java.time.ZoneId;
2223
import java.time.ZoneOffset;
2324
import java.time.format.DateTimeFormatter;
2425
import java.util.HashMap;
26+
import java.util.List;
2527
import java.util.Locale;
2628
import java.util.Map;
2729
import java.util.function.Supplier;
@@ -37,17 +39,19 @@ public DataSourceResponse.LeafMappingParametersGenerator handle(DataSourceReques
3739
}
3840

3941
return new DataSourceResponse.LeafMappingParametersGenerator(switch (fieldType) {
40-
case KEYWORD -> keywordMapping(request);
42+
case KEYWORD -> keywordMapping(false, request);
4143
case LONG, INTEGER, SHORT, BYTE, DOUBLE, FLOAT, HALF_FLOAT, UNSIGNED_LONG -> numberMapping(fieldType);
4244
case SCALED_FLOAT -> scaledFloatMapping();
4345
case COUNTED_KEYWORD -> countedKeywordMapping();
4446
case BOOLEAN -> booleanMapping();
4547
case DATE -> dateMapping();
4648
case GEO_POINT -> geoPointMapping();
47-
case TEXT -> textMapping(request);
49+
case TEXT -> textMapping(false, request);
4850
case IP -> ipMapping();
4951
case CONSTANT_KEYWORD -> constantKeywordMapping();
50-
case WILDCARD -> wildcardMapping();
52+
case WILDCARD -> wildcardMapping(false, request);
53+
case MATCH_ONLY_TEXT -> matchOnlyTextMapping(false, request);
54+
case PATTERNED_TEXT -> patternedTextMapping(false, request);
5155
});
5256
}
5357

@@ -77,7 +81,7 @@ private Supplier<Map<String, Object>> numberMapping(FieldType fieldType) {
7781
};
7882
}
7983

80-
private Supplier<Map<String, Object>> keywordMapping(DataSourceRequest.LeafMappingParametersGenerator request) {
84+
private Supplier<Map<String, Object>> keywordMapping(boolean hasParent, DataSourceRequest.LeafMappingParametersGenerator request) {
8185
return () -> {
8286
var mapping = commonMappingParameters();
8387

@@ -96,12 +100,15 @@ private Supplier<Map<String, Object>> keywordMapping(DataSourceRequest.LeafMappi
96100
}
97101
}
98102

99-
if (ESTestCase.randomDouble() <= 0.2) {
103+
if (ESTestCase.randomDouble() <= 0.3) {
100104
mapping.put("ignore_above", ESTestCase.randomIntBetween(1, 100));
101105
}
102106
if (ESTestCase.randomDouble() <= 0.2) {
103107
mapping.put("null_value", ESTestCase.randomAlphaOfLengthBetween(0, 10));
104108
}
109+
if (hasParent == false && ESTestCase.randomDouble() <= 0.2) {
110+
mapping.put("fields", stringSubField(FieldType.KEYWORD, request));
111+
}
105112

106113
return mapping;
107114
};
@@ -196,19 +203,15 @@ private Supplier<Map<String, Object>> geoPointMapping() {
196203
};
197204
}
198205

199-
private Supplier<Map<String, Object>> textMapping(DataSourceRequest.LeafMappingParametersGenerator request) {
206+
private Supplier<Map<String, Object>> textMapping(boolean hasParent, DataSourceRequest.LeafMappingParametersGenerator request) {
200207
return () -> {
201208
var mapping = new HashMap<String, Object>();
202209

203210
mapping.put("store", ESTestCase.randomBoolean());
204211
mapping.put("index", ESTestCase.randomBoolean());
205212

206-
if (ESTestCase.randomDouble() <= 0.1) {
207-
var keywordMultiFieldMapping = keywordMapping(request).get();
208-
keywordMultiFieldMapping.put("type", "keyword");
209-
keywordMultiFieldMapping.remove("copy_to");
210-
211-
mapping.put("fields", Map.of("kwd", keywordMultiFieldMapping));
213+
if (hasParent == false && ESTestCase.randomDouble() <= 0.2) {
214+
mapping.put("fields", stringSubField(FieldType.TEXT, request));
212215
}
213216

214217
return mapping;
@@ -243,17 +246,69 @@ private Supplier<Map<String, Object>> constantKeywordMapping() {
243246
};
244247
}
245248

246-
private Supplier<Map<String, Object>> wildcardMapping() {
249+
private Supplier<Map<String, Object>> wildcardMapping(boolean hasParent, DataSourceRequest.LeafMappingParametersGenerator request) {
247250
return () -> {
248251
var mapping = new HashMap<String, Object>();
249252

250-
if (ESTestCase.randomDouble() <= 0.2) {
253+
if (ESTestCase.randomDouble() <= 0.3) {
251254
mapping.put("ignore_above", ESTestCase.randomIntBetween(1, 100));
252255
}
253256
if (ESTestCase.randomDouble() <= 0.2) {
254257
mapping.put("null_value", ESTestCase.randomAlphaOfLengthBetween(0, 10));
255258
}
259+
if (hasParent == false && ESTestCase.randomDouble() <= 0.2) {
260+
mapping.put("fields", stringSubField(FieldType.PATTERNED_TEXT, request));
261+
}
262+
return mapping;
263+
};
264+
}
256265

266+
private Supplier<Map<String, Object>> stringSubField(FieldType parent, DataSourceRequest.LeafMappingParametersGenerator request) {
267+
/**
268+
* text -> keyword, wildcard
269+
* match_only_text -> keyword, wildcard
270+
* patterned_text -> keyword, wildcard
271+
* keyword -> text, match_only_text, patterned_tet, wildcard
272+
* wildcard -> keyword, text, match_only_text, patterned_text
273+
*
274+
*/
275+
return () -> {
276+
var subFields = new HashMap<FieldType, Supplier<Map<String, Object>>>();
277+
subFields.put(FieldType.KEYWORD, () -> {
278+
var mapping = keywordMapping(true, request).get();
279+
mapping.remove("copy_to");
280+
return mapping;
281+
});
282+
subFields.put(FieldType.TEXT, () -> wildcardMapping(true, request).get());
283+
subFields.put(FieldType.MATCH_ONLY_TEXT, () -> matchOnlyTextMapping(true, request).get());
284+
subFields.put(FieldType.WILDCARD, () -> wildcardMapping(true, request).get());
285+
subFields.put(FieldType.PATTERNED_TEXT, () -> matchOnlyTextMapping(true, request).get());
286+
287+
var options = subFields.entrySet().stream().filter(e -> e.getKey().equals(parent) == false).toList();
288+
var child = ESTestCase.randomFrom(options);
289+
FieldType childType = child.getKey();
290+
var childValue = child.getValue().get();
291+
childValue.put("type", childType.toString());
292+
return Map.of("subfield_" + childType, childValue);
293+
};
294+
}
295+
296+
private Supplier<Map<String, Object>> matchOnlyTextMapping(boolean hasParent, DataSourceRequest.LeafMappingParametersGenerator request) {
297+
return () -> {
298+
var mapping = new HashMap<String, Object>();
299+
if (hasParent == false && ESTestCase.randomDouble() <= 0.2) {
300+
mapping.put("fields", stringSubField(FieldType.MATCH_ONLY_TEXT, request));
301+
}
302+
return mapping;
303+
};
304+
}
305+
306+
private Supplier<Map<String, Object>> patternedTextMapping(boolean hasParent, DataSourceRequest.LeafMappingParametersGenerator request) {
307+
return () -> {
308+
var mapping = new HashMap<String, Object>();
309+
if (hasParent == false && ESTestCase.randomDouble() <= 0.2) {
310+
mapping.put("fields", stringSubField(FieldType.PATTERNED_TEXT, request));
311+
}
257312
return mapping;
258313
};
259314
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.datageneration.fields.leaf;
11+
12+
import org.elasticsearch.datageneration.FieldDataGenerator;
13+
import org.elasticsearch.datageneration.datasource.DataSource;
14+
15+
import java.util.Map;
16+
17+
public class MatchOnlyTextFieldDataGenerator implements FieldDataGenerator {
18+
private final FieldDataGenerator textGenerator;
19+
20+
public MatchOnlyTextFieldDataGenerator(DataSource dataSource) {
21+
this.textGenerator = new TextFieldDataGenerator(dataSource);
22+
}
23+
24+
@Override
25+
public Object generateValue(Map<String, Object> fieldMapping) {
26+
return textGenerator.generateValue(fieldMapping);
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.datageneration.fields.leaf;
11+
12+
import org.elasticsearch.datageneration.FieldDataGenerator;
13+
import org.elasticsearch.datageneration.datasource.DataSource;
14+
15+
import java.util.Map;
16+
17+
public class PatternedTextFieldDataGenerator implements FieldDataGenerator {
18+
private final FieldDataGenerator textGenerator;
19+
20+
public PatternedTextFieldDataGenerator(DataSource dataSource) {
21+
this.textGenerator = new TextFieldDataGenerator(dataSource);
22+
}
23+
24+
@Override
25+
public Object generateValue(Map<String, Object> fieldMapping) {
26+
return textGenerator.generateValue(fieldMapping);
27+
}
28+
}

0 commit comments

Comments
 (0)