The keyword type replaced not_analyzed

Expressing “index this exactly, do not tokenise it” used to be "type": "string", "index": "not_analyzed". From 5.0 the string type is split in two and the intent is the type name.

// 2.x
"sku": { "type": "string", "index": "not_analyzed" }

// 5.0+
"sku": { "type": "keyword" }
"name": { "type": "text", "analyzer": "product_name" }

// both, which is what most fields want
"name": {
  "type": "text",
  "fields": { "raw": { "type": "keyword" } }
}

The multi-field form is the one to reach for by default: name for searching and name.raw for sorting, aggregating and exact matching. Aggregating on a text field is either refused or requires fielddata, which loads the whole field into heap and is the classic way to take a cluster down.