@@ -82,12 +82,6 @@ private SearchContextStats(List<SearchExecutionContext> contexts) {
8282 assert contexts != null && contexts .isEmpty () == false ;
8383 }
8484
85- @ Override
86- public boolean exists (FieldName field ) {
87- var stat = cache .computeIfAbsent (field .string (), this ::makeFieldStats );
88- return stat .config .exists ;
89- }
90-
9185 private FieldStats makeFieldStats (String field ) {
9286 var stat = new FieldStats ();
9387 stat .config = makeFieldConfig (field );
@@ -103,20 +97,19 @@ private FieldConfig makeFieldConfig(String field) {
10397 // since if it's missing, deleted documents won't change that
10498 for (SearchExecutionContext context : contexts ) {
10599 if (context .isFieldMapped (field )) {
106- exists = exists || true ;
107- MappedFieldType type = context .getFieldType (field );
108- indexed = indexed && type .isIndexed ();
109- hasDocValues = hasDocValues && type .hasDocValues ();
110- if (type instanceof TextFieldMapper .TextFieldType t ) {
111- hasExactSubfield = hasExactSubfield && t .canUseSyntheticSourceDelegateForQuerying ();
112- } else {
113- hasExactSubfield = false ;
114- }
100+ var type = context .getFieldType (field );
101+ exists |= true ;
102+ indexed &= type .isIndexed ();
103+ hasDocValues &= type .hasDocValues ();
104+ hasExactSubfield &= type instanceof TextFieldMapper .TextFieldType t && t .canUseSyntheticSourceDelegateForQuerying ();
115105 } else {
116106 indexed = false ;
117107 hasDocValues = false ;
118108 hasExactSubfield = false ;
119109 }
110+ if (exists && indexed == false && hasDocValues == false && hasExactSubfield == false ) {
111+ break ;
112+ }
120113 }
121114 if (exists == false ) {
122115 // if it does not exist on any context, no other settings are valid
@@ -126,22 +119,34 @@ private FieldConfig makeFieldConfig(String field) {
126119 }
127120 }
128121
122+ private boolean fastNoCacheFieldExists (String field ) {
123+ for (SearchExecutionContext context : contexts ) {
124+ if (context .isFieldMapped (field )) {
125+ return true ;
126+ }
127+ }
128+ return false ;
129+ }
130+
131+ @ Override
132+ public boolean exists (FieldName field ) {
133+ var stat = cache .get (field .string ());
134+ return stat != null ? stat .config .exists : fastNoCacheFieldExists (field .string ());
135+ }
136+
129137 @ Override
130138 public boolean isIndexed (FieldName field ) {
131- var stat = cache .computeIfAbsent (field .string (), this ::makeFieldStats );
132- return stat .config .indexed ;
139+ return cache .computeIfAbsent (field .string (), this ::makeFieldStats ).config .indexed ;
133140 }
134141
135142 @ Override
136143 public boolean hasDocValues (FieldName field ) {
137- var stat = cache .computeIfAbsent (field .string (), this ::makeFieldStats );
138- return stat .config .hasDocValues ;
144+ return cache .computeIfAbsent (field .string (), this ::makeFieldStats ).config .hasDocValues ;
139145 }
140146
141147 @ Override
142148 public boolean hasExactSubfield (FieldName field ) {
143- var stat = cache .computeIfAbsent (field .string (), this ::makeFieldStats );
144- return stat .config .hasExactSubfield ;
149+ return cache .computeIfAbsent (field .string (), this ::makeFieldStats ).config .hasExactSubfield ;
145150 }
146151
147152 @ Override
@@ -231,7 +236,7 @@ public boolean isSingleValue(FieldName field) {
231236 var stat = cache .computeIfAbsent (fieldName , this ::makeFieldStats );
232237 if (stat .singleValue == null ) {
233238 // there's no such field so no need to worry about multi-value fields
234- if (exists ( field ) == false ) {
239+ if (stat . config . exists == false ) {
235240 stat .singleValue = true ;
236241 } else {
237242 // fields are MV per default
0 commit comments