@@ -112,8 +112,12 @@ public String buildShape(
112
112
Boolean showFieldType ,
113
113
Set <Index > successfulSearchShardIndices
114
114
) {
115
- Index firstIndex = successfulSearchShardIndices .iterator ().next ();
116
- Map <String , Object > propertiesAsMap = getPropertiesMapForIndex (firstIndex );
115
+ Index firstIndex = null ;
116
+ Map <String , Object > propertiesAsMap = null ;
117
+ if (successfulSearchShardIndices != null ) {
118
+ firstIndex = successfulSearchShardIndices .iterator ().next ();
119
+ propertiesAsMap = getPropertiesMapForIndex (firstIndex );
120
+ }
117
121
118
122
StringBuilder shape = new StringBuilder ();
119
123
shape .append (buildQueryShape (source .query (), showFieldName , showFieldType , propertiesAsMap , firstIndex ));
@@ -345,79 +349,63 @@ String buildFieldDataString(
345
349
}
346
350
347
351
String getFieldType (String fieldName , Map <String , Object > propertiesAsMap , Index index ) {
348
- String fieldType = getFieldTypeFromCache (fieldName , index );
349
- if (fieldType != null ) {
350
- if (fieldType .equals (NO_FIELD_TYPE_VALUE )) {
351
- return null ;
352
- } else {
353
- return fieldType ;
354
- }
352
+ if (propertiesAsMap == null || index == null ) {
353
+ return null ;
355
354
}
355
+ // Attempt to get field type from cache
356
+ String fieldType = getFieldTypeFromCache (fieldName , index );
356
357
357
- fieldType = getFieldTypeFromMapping (index , fieldName , propertiesAsMap );
358
358
if (fieldType != null ) {
359
- String finalFieldType = fieldType ;
360
- fieldTypeMap .computeIfAbsent (index , k -> new ConcurrentHashMap <>()).computeIfAbsent (fieldName , k -> finalFieldType );
361
359
return fieldType ;
362
360
}
363
- return null ;
364
- }
365
361
366
- String getFieldTypeFromMapping (Index index , String fieldName , Map <String , Object > propertiesAsMap ) {
367
- // Recursively find the field type from properties
368
- if (propertiesAsMap != null ) {
369
- String fieldType = findFieldTypeInProperties (propertiesAsMap , fieldName .split ("\\ ." ), 0 );
362
+ // Retrieve field type from mapping and cache it if found
363
+ fieldType = getFieldTypeFromProperties (fieldName , propertiesAsMap );
370
364
371
- // Cache the NO_FIELD_TYPE_VALUE result if no field type is found in this index
372
- if (fieldType == null ) {
373
- fieldTypeMap .computeIfAbsent (index , k -> new ConcurrentHashMap <>()).computeIfAbsent (fieldName , k -> fieldType );
374
- }
375
- return fieldType ;
376
- }
377
- return null ;
365
+ // Cache field type or NO_FIELD_TYPE_VALUE if not found
366
+ fieldTypeMap .computeIfAbsent (index , k -> new ConcurrentHashMap <>())
367
+ .putIfAbsent (fieldName , fieldType != null ? fieldType : NO_FIELD_TYPE_VALUE );
368
+
369
+ return fieldType ;
378
370
}
379
371
380
- private String findFieldTypeInProperties ( Map < String , ?> properties , String [] fieldParts , int index ) {
381
- if (index >= fieldParts . length ) {
372
+ String getFieldTypeFromProperties ( String fieldName , Map < String , Object > propertiesAsMap ) {
373
+ if (propertiesAsMap == null ) {
382
374
return null ;
383
375
}
384
376
385
- String currentField = fieldParts [ index ] ;
386
- Object currentMapping = properties . get ( currentField ) ;
377
+ String [] fieldParts = fieldName . split ( " \\ ." ) ;
378
+ Map < String , ?> currentProperties = propertiesAsMap ;
387
379
388
- // Check if current mapping is a map and contains further nested properties or a type
389
- if (currentMapping instanceof Map ) {
390
- Map <String , ?> currentMappingMap = (Map <String , ?>) currentMapping ;
380
+ for (int depth = 0 ; depth < fieldParts .length ; depth ++) {
381
+ Object currentMapping = currentProperties .get (fieldParts [depth ]);
391
382
392
- // If it has a 'properties' key, go into the nested object
393
- if (currentMappingMap .containsKey ("properties" )) {
394
- Map <String , ?> nestedProperties = (Map <String , ?>) currentMappingMap .get ("properties" );
395
- return findFieldTypeInProperties (nestedProperties , fieldParts , index + 1 );
396
- }
383
+ if (currentMapping instanceof Map ) {
384
+ Map <String , ?> currentMap = (Map <String , ?>) currentMapping ;
397
385
398
- // If it has a 'fields' key, handle multifields (e.g., title.raw) and is not the parent field (parent field case handled below)
399
- if (currentMappingMap .containsKey ("fields" ) && index + 1 < fieldParts .length ) {
400
- Map <String , ?> fieldsMap = (Map <String , ?>) currentMappingMap .get ("fields" );
401
- return findFieldTypeInProperties (fieldsMap , fieldParts , index + 1 ); // Recursively check subfield
402
- }
403
-
404
- // If it has a 'type' key, return the type. Also handles parent field case in multifields
405
- if (currentMappingMap .containsKey ("type" )) {
406
- return currentMappingMap .get ("type" ).toString ();
386
+ // Navigate into nested properties if available
387
+ if (currentMap .containsKey ("properties" )) {
388
+ currentProperties = (Map <String , ?>) currentMap .get ("properties" );
389
+ }
390
+ // Handle multifields (e.g., title.raw)
391
+ else if (currentMap .containsKey ("fields" ) && depth + 1 < fieldParts .length ) {
392
+ currentProperties = (Map <String , ?>) currentMap .get ("fields" );
393
+ }
394
+ // Return type if found
395
+ else if (currentMap .containsKey ("type" )) {
396
+ return (String ) currentMap .get ("type" );
397
+ } else {
398
+ return null ;
399
+ }
400
+ } else {
401
+ return null ;
407
402
}
408
403
}
409
404
410
405
return null ;
411
406
}
412
407
413
408
String getFieldTypeFromCache (String fieldName , Index index ) {
414
- Map <String , String > indexMap = fieldTypeMap .get (index );
415
- if (indexMap != null ) {
416
- String fieldType = indexMap .get (fieldName );
417
- if (fieldType != null ) {
418
- return fieldType ;
419
- }
420
- }
421
- return null ;
409
+ return fieldTypeMap .getOrDefault (index , new ConcurrentHashMap <>()).get (fieldName );
422
410
}
423
411
}
0 commit comments