Skip to content

Commit 91afc7f

Browse files
committed
Use optimal data structure to check for selected types
1 parent f252a5c commit 91afc7f

File tree

2 files changed

+76
-19
lines changed

2 files changed

+76
-19
lines changed

server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesFetcher.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import org.elasticsearch.tasks.CancellableTask;
3131

3232
import java.io.IOException;
33-
import java.util.Arrays;
3433
import java.util.Collections;
3534
import java.util.HashMap;
3635
import java.util.Map;
@@ -159,9 +158,11 @@ static Map<String, IndexFieldCapabilities> retrieveFieldCaps(
159158
IndexShard indexShard,
160159
boolean includeEmptyFields
161160
) {
162-
boolean includeParentObjects = checkIncludeParents(filters);
161+
Set<String> appliedFilters = Set.of(filters);
162+
boolean includeParentObjects = appliedFilters.contains("-parent") == false;
163163

164-
Predicate<MappedFieldType> filter = buildFilter(filters, types, context);
164+
Set<String> acceptedTypes = Set.of(types);
165+
Predicate<MappedFieldType> filter = buildFilter(filters, acceptedTypes, context);
165166
boolean isTimeSeriesIndex = context.getIndexSettings().getTimestampBounds() != null;
166167
var fieldInfos = indexShard.getFieldInfos();
167168
includeEmptyFields = includeEmptyFields || enableFieldHasValue == false;
@@ -205,18 +206,17 @@ static Map<String, IndexFieldCapabilities> retrieveFieldCaps(
205206
if (context.getFieldType(parentField) == null) {
206207
// no field type, it must be an object field
207208
String type = context.nestedLookup().getNestedMappers().get(parentField) != null ? "nested" : "object";
208-
IndexFieldCapabilities fieldCap = new IndexFieldCapabilities(
209-
parentField,
210-
type,
211-
false,
212-
false,
213-
false,
214-
false,
215-
null,
216-
Map.of()
217-
);
218-
219-
if (filter == null || Arrays.asList(types).contains(type)) {
209+
if (filter == null || acceptedTypes.contains(type) || appliedFilters.contains("parent")) {
210+
IndexFieldCapabilities fieldCap = new IndexFieldCapabilities(
211+
parentField,
212+
type,
213+
false,
214+
false,
215+
false,
216+
false,
217+
null,
218+
Map.of()
219+
);
220220
responseMap.put(parentField, fieldCap);
221221
}
222222
}
@@ -253,12 +253,11 @@ private static boolean alwaysMatches(QueryBuilder indexFilter) {
253253
return indexFilter == null || indexFilter instanceof MatchAllQueryBuilder;
254254
}
255255

256-
private static Predicate<MappedFieldType> buildFilter(String[] filters, String[] fieldTypes, SearchExecutionContext context) {
256+
private static Predicate<MappedFieldType> buildFilter(String[] filters, Set<String> fieldTypes, SearchExecutionContext context) {
257257
// security filters don't exclude metadata fields
258258
Predicate<MappedFieldType> fcf = null;
259-
if (fieldTypes.length > 0) {
260-
Set<String> acceptedTypes = Set.of(fieldTypes);
261-
fcf = ft -> acceptedTypes.contains(ft.familyTypeName());
259+
if (fieldTypes.isEmpty() == false) {
260+
fcf = ft -> fieldTypes.contains(ft.familyTypeName());
262261
}
263262
for (String filter : filters) {
264263
if ("parent".equals(filter) || "-parent".equals(filter)) {

server/src/test/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesFilterTests.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,64 @@ public void testIncludeAllFieldsWhenNoFieldTypeFiltering() throws IOException {
354354
assertNotNull(response.get("_index"));
355355
}
356356

357+
public void testNotIncludeParentEventWhenItsTypeIsListed() throws IOException {
358+
MapperService mapperService = createMapperService("""
359+
{ "_doc" : {
360+
"properties" : {
361+
"field1" : {
362+
"type" : "object",
363+
"properties" : {
364+
"field2" : { "type" : "keyword" }
365+
}
366+
}
367+
}
368+
} }
369+
""");
370+
SearchExecutionContext sec = createSearchExecutionContext(mapperService);
371+
372+
Map<String, IndexFieldCapabilities> response = FieldCapabilitiesFetcher.retrieveFieldCaps(
373+
sec,
374+
s -> true,
375+
new String[] { "-parent" },
376+
new String[] { "keyword", "object" },
377+
FieldPredicate.ACCEPT_ALL,
378+
getMockIndexShard(),
379+
true
380+
);
381+
assertNull(response.get("field1"));
382+
assertNotNull(response.get("field1.field2"));
383+
assertNull(response.get("_index"));
384+
}
385+
386+
public void testIncludeParentEventWhenItsTypeIsNotListed() throws IOException {
387+
MapperService mapperService = createMapperService("""
388+
{ "_doc" : {
389+
"properties" : {
390+
"field1" : {
391+
"type" : "object",
392+
"properties" : {
393+
"field2" : { "type" : "keyword" }
394+
}
395+
}
396+
}
397+
} }
398+
""");
399+
SearchExecutionContext sec = createSearchExecutionContext(mapperService);
400+
401+
Map<String, IndexFieldCapabilities> response = FieldCapabilitiesFetcher.retrieveFieldCaps(
402+
sec,
403+
s -> true,
404+
new String[] { "parent" },
405+
new String[] { "keyword" },
406+
FieldPredicate.ACCEPT_ALL,
407+
getMockIndexShard(),
408+
true
409+
);
410+
assertNotNull(response.get("field1"));
411+
assertNotNull(response.get("field1.field2"));
412+
assertNull(response.get("_index"));
413+
}
414+
357415
private IndexShard getMockIndexShard() {
358416
IndexShard indexShard = mock(IndexShard.class);
359417
when(indexShard.getFieldInfos()).thenReturn(FieldInfos.EMPTY);

0 commit comments

Comments
 (0)