occupation is a text field,
occupation.keyword is a keyword field. Both are using the same underlying data, but they index it in different ways.
Text fields index individual words and allow full text search (how exactly this works can be configured - Text field type | Elasticsearch Reference [7.12] | Elastic ). That's why
occupation: "Sales" shows the "Sales Engineer" result. By default they are also case-insensitive.
Keyword fields on the other hand are simpler - they just match the perfect phrase ( Keyword type family | Elasticsearch Reference [7.12] | Elastic ). It also allows to do aggregations (e.g. "give me the top 5 occupations and their respective counts" - you can do this with visualizations), something that's not possible with text fields.
Which one to use depends on your use case - an
id field for example doesn't make sense to index as a text field as you never want partial matches and case sensitivity matters. A
tweet field very likely should be a text field, because you rarely want to match the perfect text, but search for parts of the whole message.
As Elasticsearch can't tell what you are planning to do, by default strings are indexed twice - as keyword and as text. You can (and should) configure this in the mapping though once you know what you want to do.
text field type: Full text search
keyword field type: Perfect matches (ids, iso country codes, ...) and aggregations