@@ -64,16 +64,104 @@ Some important points:
6464* It is the field _value_ which is copied, not the terms (which result from the analysis process).
6565* The original <<mapping-source-field,`_source`>> field will not be modified to show the copied values.
6666* The same value can be copied to multiple fields, with `"copy_to": [ "field_1", "field_2" ]`
67- * You cannot copy recursively via intermediary fields such as a `copy_to` on
68- `field_1` to `field_2` and `copy_to` on `field_2` to `field_3` expecting
69- indexing into `field_1` will eventuate in `field_3`, instead use copy_to
70- directly to multiple fields from the originating field.
67+ * You cannot copy recursively using intermediary fields.
68+ The following configuration will not copy data from `field_1` to `field_3`:
69+ +
70+ [source,console]
71+ ----
72+ PUT bad_example_index
73+ {
74+ "mappings": {
75+ "properties": {
76+ "field_1": {
77+ "type": "text",
78+ "copy_to": "field_2"
79+ },
80+ "field_2": {
81+ "type": "text",
82+ "copy_to": "field_3"
83+ },
84+ "field_3": {
85+ "type": "text"
86+ }
87+ }
88+ }
89+ }
90+ ----
91+ Instead, copy to multiple fields from the source field:
92+ +
93+ [source,console]
94+ ----
95+ PUT good_example_index
96+ {
97+ "mappings": {
98+ "properties": {
99+ "field_1": {
100+ "type": "text",
101+ "copy_to": ["field_2", "field_3"]
102+ },
103+ "field_2": {
104+ "type": "text"
105+ },
106+ "field_3": {
107+ "type": "text"
108+ }
109+ }
110+ }
111+ }
112+ ----
113+
114+ NOTE: `copy_to` is not supported for field types where values take the form of objects, e.g. `date_range`.
115+
116+ [float]
117+ [[copy-to-dynamic-mapping]]
118+ ==== Dynamic mapping
119+
120+ Consider the following points when using `copy_to` with dynamic mappings:
121+
71122* If the target field does not exist in the index mappings, the usual
72123<<dynamic-mapping,dynamic mapping>> behavior applies. By default, with
73124<<dynamic,`dynamic`>> set to `true`, a non-existent target field will be
74- dynamically added to the index mappings. If `dynamic` is set to `false`, the
125+ dynamically added to the index mappings.
126+ * If `dynamic` is set to `false`, the
75127target field will not be added to the index mappings, and the value will not be
76- copied. If `dynamic` is set to `strict`, copying to a non-existent field will
128+ copied.
129+ * If `dynamic` is set to `strict`, copying to a non-existent field will
77130result in an error.
131+ +
132+ ** If the target field is nested, then `copy_to` fields must specify the full path to the nested field.
133+ Omitting the full path will lead to a `strict_dynamic_mapping_exception`.
134+ Use `"copy_to": ["parent_field.child_field"]` to correctly target a nested field.
135+ +
136+ For example:
137+ +
138+ [source,console]
139+ --------------------------------------------------
140+ PUT /test_index
141+ {
142+ "mappings": {
143+ "dynamic": "strict",
144+ "properties": {
145+ "description": {
146+ "properties": {
147+ "notes": {
148+ "type": "text",
149+ "copy_to": [ "description.notes_raw"], <1>
150+ "analyzer": "standard",
151+ "search_analyzer": "standard"
152+ },
153+ "notes_raw": {
154+ "type": "keyword"
155+ }
156+ }
157+ }
158+ }
159+ }
160+ }
161+ --------------------------------------------------
78162
79- NOTE: `copy_to` is _not_ supported for field types where values take the form of objects, e.g. `date_range`
163+ <1> The `notes` field is copied to the `notes_raw` field. Targeting `notes_raw` alone instead of `description.notes_raw`
164+ would lead to a `strict_dynamic_mapping_exception`.
165+ +
166+ In this example, `notes_raw` is not defined at the root of the mapping, but under the `description` field.
167+ Without the fully qualified path, {es} would interpret the `copy_to` target as a root-level field, not as a nested field under `description`.
0 commit comments