Repository: elastic/ecs

Issue:
Support `match_only_text` type fallback for ES 6 artifacts
The `match_only_text` field data type will be introduced in Elasticsearch 7.14 and an upcoming ECS version via an [RFC proposal](https://github.com/elastic/ecs/blob/master/rfcs/text/0023-match_only_text-data-type.md).

Since `match_only_text` is a feature available in 7.14+, artifacts generated targeting ES 6.x will need to fall back to using the `text` data type.


Discussion:
Waiting on #1527 to implement this support.

Resolving patch:
diff --git a/scripts/generators/es_template.py b/scripts/generators/es_template.py
--- a/scripts/generators/es_template.py
+++ b/scripts/generators/es_template.py
@@ -11,7 +11,8 @@
 TYPE_FALLBACKS = {
     'constant_keyword': 'keyword',
     'wildcard': 'keyword',
-    'version': 'keyword'
+    'version': 'keyword',
+    'match_only_text': 'text'
 }
 
 # Composable Template
@@ -283,5 +284,13 @@ def es6_type_fallback(mappings):
             if fallback_type:
                 mappings[name]['type'] = fallback_type
                 field_or_multi_field_datatype_defaults(mappings[name])
+        # support multi-fields
+        if 'fields' in details:
+            # potentially multiple multi-fields
+            for field_name, field_value in details['fields'].items():
+                fallback_type = TYPE_FALLBACKS.get(field_value['type'])
+                if fallback_type:
+                    mappings[name]['fields'][field_name]['type'] = fallback_type
+                    field_or_multi_field_datatype_defaults(mappings[name]['fields'][field_name])
         if 'properties' in details:
             es6_type_fallback(details['properties'])


Test patch:
diff --git a/scripts/tests/test_es_template.py b/scripts/tests/test_es_template.py
--- a/scripts/tests/test_es_template.py
+++ b/scripts/tests/test_es_template.py
@@ -222,6 +222,112 @@ def test_es6_fallback_base_case_constant_keyword(self):
         es_template.es6_type_fallback(test_map)
         self.assertEqual(test_map, exp)
 
+    def test_es6_fallback_base_case_match_only_text(self):
+        test_map = {
+            "field": {
+                "name": "field",
+                "type": "match_only_text"
+            }
+        }
+
+        exp = {
+            "field": {
+                "name": "field",
+                "type": "text",
+                "norms": False
+            }
+        }
+
+        es_template.es6_type_fallback(test_map)
+        self.assertEqual(test_map, exp)
+
+    def test_es6_fallback_recursive_case_match_only_text(self):
+        test_map = {
+            "top_field": {
+                "properties": {
+                    "field": {
+                        "name": "field",
+                        "type": "match_only_text"
+                    }
+                }
+            }
+        }
+
+        exp = {
+            "top_field": {
+                "properties": {
+                    "field": {
+                        "name": "field",
+                        "type": "text",
+                        "norms": False
+                    }
+                }
+            }
+        }
+
+        es_template.es6_type_fallback(test_map)
+        self.assertEqual(test_map, exp)
+
+    def test_es6_fallback_multifield_base_match_only_text(self):
+        test_map = {
+            "field": {
+                "name": "field",
+                "fields": {
+                    "text": {
+                        "type": "match_only_text"
+                    }
+                }
+            }
+        }
+
+        exp = {
+            "field": {
+                "name": "field",
+                "fields": {
+                    "text": {
+                        "type": "text",
+                        "norms": False
+                    }
+                }
+            }
+        }
+
+        es_template.es6_type_fallback(test_map)
+        self.assertEqual(test_map, exp)
+
+    def test_es6_fallback_multifield_recursive_match_only_text(self):
+        test_map = {
+            "top_field": {
+                "properties": {
+                    "field": {
+                        "fields": {
+                            "text": {
+                                "type": "match_only_text"
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        exp = {
+            "top_field": {
+                "properties": {
+                    "field": {
+                        "fields": {
+                            "text": {
+                                "type": "text",
+                                "norms": False
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        es_template.es6_type_fallback(test_map)
+        self.assertEqual(test_map, exp)
+
     def test_component_composable_template_name(self):
         version = "1.8"
         test_map = {