Custom _all Fieldsedit

In Metadata: _all Field, we explained that the special _all field indexes the values from all other fields as one big string. Having all fields indexed into one field is not terribly flexible, though. It would be nice to have one custom _all field for the person’s name, and another custom _all field for the address.

Elasticsearch provides us with this functionality via the copy_to parameter in a field mapping:

PUT /my_index
{
    "mappings": {
        "person": {
            "properties": {
                "first_name": {
                    "type":     "string",
                    "copy_to":  "full_name" 
                },
                "last_name": {
                    "type":     "string",
                    "copy_to":  "full_name" 
                },
                "full_name": {
                    "type":     "string"
                }
            }
        }
    }
}

The values in the first_name and last_name fields are also copied to the full_name field.

With this mapping in place, we can query the first_name field for first names, the last_name field for last name, or the full_name field for first and last names.

Mappings of the first_name and last_name fields have no bearing on how the full_name field is indexed. The full_name field copies the string values from the other two fields, then indexes them according to the mapping of the full_name field only.

The copy_to setting will not work on a multi-field. If you attempt to configure your mapping this way, Elasticsearch will throw an exception.

Why? Multi-fields are simply indexing the "main" field a different way; they don’t have their own source. Which means there is no source to copy_to a different field.

You can easily copy_to the "main" field to achieve the same effect:

PUT /my_index
{
    "mappings": {
        "person": {
            "properties": {
                "first_name": {
                    "type":     "string",
                    "copy_to":  "full_name", 
                    "fields": {
                        "raw": {
                            "type": "string",
                            "index": "not_analyzed"
                        }
                    }
                },
                "full_name": {
                    "type":     "string"
                }
            }
        }
    }
}

copy_to is placed on the "main" field rather than the multi-field