How hiberante search creates index fields mapping?

As I already told you in another post, Hibernate Search 5 did not create this mapping. Hibernate Search did not know about this field, so it didn’t add it to the Elasticsearch schema, and Elasticsearch added it automatically the first time a document with that field was indexed:

The only way to get that exact behavior in Hibernate Search 6 would be to go full native: define your mapping as JSON, transform document data to JSON in the bridge, and define your search predicates as JSON in the Search DSL.

Alternatively, you could alter your bridge to give the keyword type to all your dynamic fields:

 public class ResourceAttributesBinder implements PropertyBinder {
     @Override
     public void bind(PropertyBindingContext context) {
         context.dependencies().useRootOnly();
         PojoModelProperty bridgedElement = context.bridgedElement();
 
         context.indexSchemaElement().fieldTemplate( 
                 "attributeFieldValueTemplate_default",
-                 f -> f.asString().analyzer( "english" )
+                 f -> f.asString()
             .matchingPathGlob( "*.*" );
         
         context.indexSchemaElement().objectFieldTemplate( "attributeObjectFieldTemplate_default" );
 
         context.bridge(Map.class, new ResourceAttributesPropertyBridge());
     }
 }

Then don’t use archetype.archetypeId.keyword in your search queries, but just archetype.archetypeId.

And, last solution, if you need both full-text search and keyword search you could define two field templates in your binder:

 public class ResourceAttributesBinder implements PropertyBinder {
     @Override
     public void bind(PropertyBindingContext context) {
         context.dependencies().useRootOnly();
         PojoModelProperty bridgedElement = context.bridgedElement();
 
+        context.indexSchemaElement().fieldTemplate( 
+                "attributeFieldValueTemplate_keyword",
+                 f -> f.asString()
+            .matchingPathGlob( "*.*_keyword" );
         context.indexSchemaElement().fieldTemplate( 
                 "attributeFieldValueTemplate_default",
                  f -> f.asString().analyzer( "english" )
             .matchingPathGlob( "*.*" );
         
         context.indexSchemaElement().objectFieldTemplate( "attributeObjectFieldTemplate_default" );
 
         context.bridge(Map.class, new ResourceAttributesPropertyBridge());
     }
 }

And make sure to populate both fields in your bridge:

 public class ResourceAttributesPropertyBridge implements PropertyBridge<Map> {
 
     private final IndexObjectFieldReference fieldReference;
 
     public ResourceAttributesPropertyBridge(IndexObjectFieldReference fieldReference) {
         this.fieldReference = fieldReference;
     }
 
     @Override
     public void write(DocumentElement target, Map bridgedElement, PropertyBridgeWriteContext context) {
         System.out.println("######bridgedElement#######"+ bridgedElement);
         final Map<String, Object> indexMap = (Map<String, Object>) bridgedElement;
         if (!ObjectUtils.isEmpty(indexMap)) {
             for (Map.Entry<String, Object> entry : indexMap.entrySet()) {
                 final List<String> attributeKeys = getIndexedAttributes().get(entry.getKey());
                 if (!ObjectUtils.isEmpty(attributeKeys)) {
                     final Map<String, Object> resourceAttributes = (Map<String, Object>) 
                     DocumentElement attributesObject = target.addObject( entry.getKey() );
                      for (String attributeKey : attributeKeys) {
+                       String attributeKeywordFieldName = attributeKey + "_keyword";
                         final Object attributeValue = resourceAttributes.get(attributeKey);
                         if (!ObjectUtils.isEmpty(attributeValue)) {
                             if (attributeValue instanceof List) {
                                 ((List<String>) attributeValue).forEach(item -> {
                                     if (log.isTraceEnabled()) {
                                         log.trace("Adding field {} with value {} to document.", fieldName, item);
                                     }
                                     attributesObject.addValue(attributeKey,item);
+                                    attributesObject.addValue(attributeKeywordFieldName,item);
                                 });
                             } else {
                                 if (log.isTraceEnabled()) {
                                     log.trace("Adding field {} with value {} to document.", fieldName, attributeValue.toString());
                                 }
                                 attributesObject.addValue(attributeKey,item);
+                                attributesObject.addValue(attributeKeywordFieldName,item);
                             }
                         }
                     }
                 }
             }
         }
     }
 }

Then don’t use archetype.archetypeId.keyword in your search queries, but archetype.archetypeId_keyword.