Skip to content

Commit e2c2a7c

Browse files
committed
add dimension filter to field caps
1 parent a231726 commit e2c2a7c

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ static Map<String, IndexFieldCapabilities> retrieveFieldCaps(
161161
boolean includeEmptyFields
162162
) {
163163
boolean includeParentObjects = checkIncludeParents(filters);
164+
boolean includeDimensions = checkIncludeDimensions(filters);
164165

165166
Predicate<MappedFieldType> filter = buildFilter(filters, types, context);
166167
boolean isTimeSeriesIndex = context.getIndexSettings().getTimestampBounds() != null;
@@ -169,10 +170,10 @@ static Map<String, IndexFieldCapabilities> retrieveFieldCaps(
169170
Map<String, IndexFieldCapabilities> responseMap = new HashMap<>();
170171
for (Map.Entry<String, MappedFieldType> entry : context.getAllFields()) {
171172
final String field = entry.getKey();
172-
if (fieldNameFilter.test(field) == false) {
173+
MappedFieldType ft = entry.getValue();
174+
if (fieldNameFilter.test(field) == false && ((ft.isDimension() && includeDimensions) == false)) {
173175
continue;
174176
}
175-
MappedFieldType ft = entry.getValue();
176177
if ((includeEmptyFields || ft.fieldHasValue(fieldInfos))
177178
&& (fieldPredicate.test(ft.name()) || context.isMetadataField(ft.name()))
178179
&& (filter == null || filter.test(ft))) {
@@ -234,6 +235,15 @@ private static boolean checkIncludeParents(String[] filters) {
234235
return true;
235236
}
236237

238+
private static boolean checkIncludeDimensions(String[] filters) {
239+
for (String filter : filters) {
240+
if ("+dimension".equals(filter)) {
241+
return true;
242+
}
243+
}
244+
return false;
245+
}
246+
237247
private static boolean canMatchShard(
238248
ShardId shardId,
239249
QueryBuilder indexFilter,
@@ -267,7 +277,8 @@ private static Predicate<MappedFieldType> buildFilter(String[] filters, String[]
267277
}
268278

269279
for (String filter : filters) {
270-
if ("parent".equals(filter) || "-parent".equals(filter)) {
280+
// These "filters" are handled differently, in that they are not ANDed with the field name pattern
281+
if ("parent".equals(filter) || "-parent".equals(filter) || "+dimension".equals(filter)) {
271282
continue;
272283
}
273284
Predicate<MappedFieldType> next = switch (filter) {

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import org.apache.lucene.index.FieldInfos;
1313
import org.elasticsearch.common.Strings;
14+
import org.elasticsearch.common.settings.Settings;
1415
import org.elasticsearch.index.mapper.MapperService;
1516
import org.elasticsearch.index.mapper.MapperServiceTestCase;
1617
import org.elasticsearch.index.query.SearchExecutionContext;
@@ -97,6 +98,56 @@ public void testMetadataFilters() throws IOException {
9798
}
9899
}
99100

101+
public void testDimensionFilters() throws IOException {
102+
MapperService mapperService = createMapperService(
103+
Settings.builder().put("index.mode", "time_series").put("index.routing_path", "dim.*").build(),
104+
"""
105+
{ "_doc" : {
106+
"properties" : {
107+
"metric" : { "type" : "long" },
108+
"dimension_1" : { "type" : "keyword", "time_series_dimension" : "true" },
109+
"dimension_2" : { "type" : "long", "time_series_dimension" : "true" }
110+
}
111+
} }
112+
"""
113+
);
114+
SearchExecutionContext sec = createSearchExecutionContext(mapperService);
115+
116+
/*
117+
{
118+
// First, test without the filter
119+
Map<String, IndexFieldCapabilities> response = FieldCapabilitiesFetcher.retrieveFieldCaps(
120+
sec,
121+
s -> s.equals("metric"),
122+
Strings.EMPTY_ARRAY,
123+
Strings.EMPTY_ARRAY,
124+
FieldPredicate.ACCEPT_ALL,
125+
getMockIndexShard(),
126+
true
127+
);
128+
assertNotNull(response.get("metric"));
129+
assertNull(response.get("dimension_1"));
130+
assertNull(response.get("dimension_2"));
131+
}
132+
133+
*/
134+
{
135+
// then, test with the filter
136+
Map<String, IndexFieldCapabilities> response = FieldCapabilitiesFetcher.retrieveFieldCaps(
137+
sec,
138+
s -> s.equals("metric"),
139+
new String[] { "+dimension" },
140+
Strings.EMPTY_ARRAY,
141+
FieldPredicate.ACCEPT_ALL,
142+
getMockIndexShard(),
143+
true
144+
);
145+
assertNotNull(response.get("dimension_1"));
146+
assertNotNull(response.get("dimension_2"));
147+
assertNotNull(response.get("metric"));
148+
}
149+
}
150+
100151
public void testExcludeMultifields() throws IOException {
101152
MapperService mapperService = createMapperService("""
102153
{ "_doc" : {

0 commit comments

Comments
 (0)